java并发-线程池总结-原理

原创
2019/12/15 10:27
阅读数 42

线程池的构成

1.存储线程引用的容器,间接获得了运行的总线程数量,存储引用使用来停止线程的。

2.记录线程池的状态(未初始化,运行中,停止)

3.暂存任务的容器,一般都是阻塞队列,因为阻塞队列本身提供了等待和阻塞的功能

如果使用容器记录当前线程池内运行状态的线程,那么就只需要一个普通变量了。

还需要以下变量来让用户优化性能

1.初始线程个数

2.最大线程个数

3.最大任务个数

4.线程空闲停止超时时间

思考:

存储线程的容器使用什么容器性能最好呢?首先,所有的线程都会去争夺任务。。。

来研究jdk8的代码

ThreadPoolExecutor类

ctl是32位的整数,高3位是线程池的状态,其余各位就是工作线程的个数

11100000000000000000000000000000 runing

00000000000000000000000000000000 shutdown

01000000000000000000000000000000 stop

10000000000000000000000000000000 tidying

11000000000000000000000000000000 terminated

HashSet存线程引用

首先明白,谁触发了哪些动作

1.谁触发了哪些动作?调用threadPoolExecutor类的方法的线程,外部调用者

2.哪些动作?

 1.工作线程的新建 (都是由外部调用者触发工作线程的新建,新增)

2.工作线程的销毁(外部调用者会,线程池内部自己也会)

我们一个一个方法的看

1.addWorker方法

  所有的方法,估计开始都会判断线程池是否已经关闭,毋庸置疑。

if (rs >= SHUTDOWN && ! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty()))是什么意思?

线程池是一个内的工作线程是被动启动的,不是在线程池的构造函数内被启动的,这样做的目的,就是为了节省资源,如果一开始就启动所有的核心线程,那么还是要消耗不少时间的。

当线程池被创建,第一个submit方法调用,传入任务,会封装成FutrueTask,如果没有工作线程,则会创建一个工作线程,执行此任务,之后,这个工作线程就会拉取阻塞任务队列,这个拉取还是具有超时时间的,是keepAlive时间。

当再调用submit方法,如果发现没有空闲的工作线程,那么就会判断是否已经达到最大工作线程大小,如果没有,则创建线程执行任务。

如果已经达到最大工作线程大小,则把任务投递到阻塞任务队列,当工作线程有执行完任务的,将会自动去取任务来执行。

但是,当阻塞队列满了,则会执行拒绝策略。

如何关闭线程池?关闭线程池的时候,其内部的执行原理是什么呢?

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部