线程池里面包含了许多线程,可以供我们去使用,而避免了频繁的创建线程以及销毁线程,主要目的就是为了提高开发效率。那么我们如何实现一个自己的“线程池”呢

首先我们来看一下线程池的组成部分有哪些

  1. 有一个类,这个类表示工作线程,也就是用来执行任务的线程,借助这个类可以表示多个线程
  2. 还得有一个类来描述具体线程要做的任务是什么,直接使用Runnable即可
  3. 还需要一个阻塞队列来组织若干个任务。
  4. 好需要一个List来组织若干个线程

线程池核心操作

  1. execute
    创建线程并且将要执行的任务放到阻塞队列中去。
  2. shutdown
    调用List中的每个线程的interrupt方法去终止线程。由于interrupt方法调用之后可能线程还没执行完,所以还需要调用join()方法让所有的线程执行完。

下面我们来看具体代码

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;public class ThreadDemo21 { //实现一个线程池static class Worker extends Thread {//使用这个类来描述工作线程是啥样的private BlockingQueue<Runnable> blo;//Worker这个线程需要从阻塞队列中获取任务过来执行//所以需要获取到这个阻塞队列的实例,这个阻塞队列里面就是每一个任务public Worker(BlockingQueue<Runnable> blo) {//通过构造方法这个阻塞队列的实例传递过来//让这个线程里面能够获取到整个阻塞队列,进而获取到里面的任务this.blo = blo;}@Overridepublic void run() {try {while (!Thread.currentThread().isInterrupted()) {Runnable command = blo.take();//当这个线程不被终止的情况下,就会一直在这个阻塞队列中获取任务过来执行command.run();//这个线程一直在阻塞队列中获取到任务然后执行。}} catch (InterruptedException e) {System.out.println(("线程被结束"));}}}static class MyThreadPoll {//这个就是代表一个线程池private BlockingQueue<Runnable> blo = new LinkedBlockingDeque<>();//这个阻塞队列用来存放每一个任务//Worker线程就从这个阻塞队列中取一些任务过来执行//这个顺序表用来组织若干个工作线程private List<Worker> list = new ArrayList<>();private static final int workcount = 10;//这个代表线程的指定个数,如果小于它,就新创建线程来作为工作线程//如果大于它,就不再创建//实现execute方法和shutdown方法public void execute(Runnable command) throws InterruptedException {//这个方法的作用就是将任务加到阻塞队列中,线程执行的时候if (list.size() < workcount) {Worker worker = new Worker(blo);//创建线程来执行任务worker.start();list.add(worker);//把这个线程加入到表中}//就是在这个阻塞队列中取任务blo.put(command);}public void shutdown() throws InterruptedException {//终止掉所有的线程,也就是依次调用每个线程的interrupt方法//只要调用这个方法,就会调用表中的每个线程的interrupt方法来中断他们。for (Worker worker : list) {//遍历数组,然后依次调用里面的线程的interrupt方法来中断worker.interrupt();//每个线程执行这个方法的时候,很有可能执行到一半被触发异常。由于不涉及阻塞操作,所以是把判断条件设置为true。所以需要等while循环执行一半才会终止线程//所以还需要一个jion操作去等待线程结束}for (Worker worker : list) {//还需要等待每个线程执行结束//从收到异常到线程结束,中间可能还需要执行一些逻辑,尤其是catch里面的代码//当shutdown结束之后,意味着所有的线程一定都结束了。worker.join();}}}public static void main(String[] args) throws InterruptedException {MyThreadPoll p = new MyThreadPoll();p.execute(new Runnable() {@Overridepublic void run() {System.out.println(("我是你爸爸"));}});}
}

Worker这个类就代表线程,里面包含着线程执行的操作。也就是从阻塞队列中取得任务并且执行它,只要线程没有被中断,就会循环取任务并且执行。通过构造方法将阻塞队列传递归来

ThreadPoll就代表一个线程池,里面定义一个阻塞队列以及一个List,以及线程数量的阈值。execute方法里面就创建线程,同时通过构造方法将阻塞队列传过去。然后将这个任务放到阻塞队列中去。再把这个线程放到List中
shutdown方法则用来终止所有的线程

线程池其实本质上也是一个生产者-消费者模型。线程池中的execute方法用来生产任务,当调用这个方法的时候就把任务引用传过来,然后加入到阻塞队列中。然后每一个线程则是消费者,在阻塞队列中获取任务引用,然后直接调用这个任务的run方法即可执行。阻塞队列则是一个交易所。

如何实现一个“线程池”相关推荐

  1. java 手编线程池_死磕 java线程系列之自己动手写一个线程池

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. (手机横屏看源码更方便) 问题 (1)自己动手写一个线程池需要考虑哪些因素? (2)自己动手写 ...

  2. 随笔之如何实现一个线程池

    为什么80%的码农都做不了架构师?>>>    一 缘由:     最近因工作问题,需要实现一个简单的线程池,满足一下要求, 可伸缩,即一旦发现线程不够用,则可以动态增加线程.(至于 ...

  3. 一个线程池中的线程异常了,那么线程池会怎么处理这个线程?

    一个线程池中的线程异常了,那么线程池会怎么处理这个线程? 参考文章: (1)一个线程池中的线程异常了,那么线程池会怎么处理这个线程? (2)https://www.cnblogs.com/fangua ...

  4. 工作中如何使用线程池的?自己如何定义一个线程池?

    工作中如何使用线程池的?自己如何定义一个线程池? import java.util.concurrent.*;public class MyThreadPoolDemo {public static ...

  5. 设置iis网页服务器cpu占比,为什么iis的一个线程池占了100%cpu

    为什么iis的一个线程池占了快100%cpu, 这个站点是跑asp.net web api的,大多是数据库的操作. 当回收这个线程池后几分钟,cpu使用率就降下来了. 可是隔一天半天的再去服务器看,c ...

  6. 程序随笔——C++实现的一个线程池

    1.线程池简介 我们知道在线程池是一种多线程处理形式,处理过程中我们将相应的任务提交给线程池,线程池会分配对应的工作线程执行任务或存放在任务队列中,等待执行. 面向对象编程中,创建和销毁对象是需要消耗 ...

  7. 一个有趣的问题 : 如何设计一个线程池

    理解Java并发工具包线程池的设计 深度解读 java 线程池设计思想及源码实现 分布式锁unlock 问题产生原因分析: Step 1 :线程A先上同一个锁(Key)(20秒), 然后执行耗时业务, ...

  8. 【重难点】【JUC 05】线程池核心设计与实现、线程池使用了什么设计模式、要你设计的话,如何实现一个线程池

    [重难点][JUC 05]线程池核心设计与实现.线程池使用了什么设计模式.要你设计的话,如何实现一个线程池 文章目录 [重难点][JUC 05]线程池核心设计与实现.线程池使用了什么设计模式.要你设计 ...

  9. 面试官:如何评估一个线程池需要设置多少个线程

    作者 | 丁威       责编 | 欧阳姝黎 见字如面,我是威哥,一个从普通二本院校毕业,从未曾接触分布式.微服务.高并发到通过技术分享实现职场蜕变,成长为 RocketMQ 社区优秀布道师.大厂资 ...

最新文章

  1. android 8.0以后(sdk26)启动前台服务的问题探究
  2. 运营体系_用户运营系统论:解构复杂产品的大规模用户运营体系
  3. iis 404错误从定向完美方案
  4. 萝卜源码前后端源码 附打包APP的教程
  5. 关于equals和hashCode
  6. 【渝粤教育】21秋期末考试市场营销10256k2
  7. 【三维路径规划】基于matlab A_star算法无人机山地三维路径规划【含Matlab源码 266期】
  8. php留言板源码无需数据库,无需数据库的PHP留言板
  9. INVEST模型生境质量评价之威胁源数据处理
  10. 两个很棒的爬虫智能解析库,通配大部分网页!
  11. 电脑浏览器安全获取京东cookie
  12. [随笔]_ELVE_git命令复习
  13. 互联网定律及效应汇编
  14. 正弦定理和余弦定理_教师招聘 数学中学说课稿 《余弦定理》
  15. Bazinga HDU - 5510
  16. 第五章-2 dns劫持 - Ettercap
  17. AEAI Portal中集成百度地图
  18. 深圳物流 inurl php id=,免费快递在线下单接口对接文档-(PHP)
  19. mysql3306端口被占用无法终止_Mysql3306端口被占用无法启动解决办法
  20. 互联网晚报 | 1月27日 星期四 | 微信推出“拜年红包”功能;快手推出蓝领招聘平台“快招工”;B站正式登陆PS5平台...

热门文章

  1. VMware Workstation 14 官方免费正式版
  2. Windows 文本大文件查看工具
  3. 合肥工业大学2022大数据技术实验一
  4. 黑猴子的家:JavaWeb 之 Title icon
  5. JVM内存模型JVM内存模型
  6. 给静态图片添加动态效果
  7. 关于耳机与电脑连接断断续续问题的解决办法
  8. 看了中国与别国的科研差距后,究竟什么才是真正的科研精神?
  9. 第19节 HSRP-热备份路由协议原理及实验演示—基于Cisco Packet Tracer
  10. 术语FXO和FXS的含义是什么?[图]