ThreadPoolExcutor源码个人浅析(一)
一、引言
由于前不久面试的时候涉及到这部分的知识点,比较不熟,所以在此写篇博客,给自己加深下理解,也方便忘记的时候再捡起来。
二、源码浅析
俗话说,掌握一项技能,要知其然,亦要知其所以然。要用当然容易,不过不知其原理,哪天踩坑的时候就得多花费很多时间了。话不多说,先来看下ThreadPoolExcutor的内部都有些啥。
首先,先看下这个类的属性:
可以看到这个变量是原子类型,也就是说对于这个变量的操作都是原子操作。这个变量是这个类的核心,然后在new的时候存了两个参数进去分别是对应:各个线程状态(runState)和所有有效的线程数(workerCount)。
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
COUNT_BITS不多说了,是用来做计算的,占据了1个int的低29位,代表了workerCount所占的位数。
private static final int COUNT_BITS = Integer.SIZE - 3;
可以看出,CAPACITY为1左移29位减1,为536870911,亦可看出,这个值即是workerCount的最大值,由CAPACITY表示。
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
以下是5种线程状态:
// runState is stored in the high-order bits 由高3位表示
1.接受新任务,并处理队列任务,高3位全为1,值为-536870912
private static final int RUNNING = -1 << COUNT_BITS;
2.不接受新任务,但会处理队列任务,全为0,值为0
private static final int SHUTDOWN = 0 << COUNT_BITS;
3.不接受新任务,不会处理队列任务,而且会中断正在处理过程中的任务,高3位为001,值为536870912
private static final int STOP = 1 << COUNT_BITS;
4.所有的任务已结束,workerCount为0,线程过渡到TIDYING状态,将会执行terminated()钩子方法,高3位为010,值为1073741824
private static final int TIDYING = 2 << COUNT_BITS;
5.terminated()方法已经完成,高3位为011,值为1610612736
private static final int TERMINATED = 3 << COUNT_BITS;
可知,这5个状态的值是依次递增的,至于各个状态之间如何切换,我们可通过注释得知:
* RUNNING -> SHUTDOWN
* On invocation of shutdown(), perhaps implicitly in finalize()
* (RUNNING or SHUTDOWN) -> STOP
* On invocation of shutdownNow()
* SHUTDOWN -> TIDYING
* When both queue and pool are empty
* STOP -> TIDYING
* When pool is empty
* TIDYING -> TERMINATED
* When the terminated() hook method has completed
至于后面获取线程状态和工作线程数的方法:
一个是取高3位,一个是取低29位,没什么好说的
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
先写这么多,下一篇再来研究下ThreadPoolExcutor的构造方法部分。
参考内容来源: