本文将ThreadPoolExecutor高深的位运算转换为二进制,以便更直观的理解方法和属性的使用。对加入线程池,执行worker的线程,释放worker的线程,终止线程池等进行细致的理解,以求每个判断,每行代码都能理解。Doug Lea的ThreadPoolExecutor代码实现真的是我们学习的榜样
属性
NOTE: 代码中的位运算不好直观,我们学习时可以将他们转成十进制和二进制,直观便于理解。使用以下方法操作进制间的转换
1、二进制 -> 十进制 Integer.parseInt(“00111100”, 2)
2、十进制 -> 二进制 Integer.toBinaryString(1)
/**
*
* <pre>
* ctl即是又是
* workerCount:表示有效的线程数
* runState: 表示线程池的状态
* </pre>
* <pre>
* Run state is stored in the high-order bits; worker count is stored in the low-order bits. 解释如下:
* | --- 高位 --- | --- 低位 --- |
* | -536870912 --> 0 --> 536870912 |
* | --- 线程状态 --- | --- 线程数量 --- |
* 所以线程状态的变化轨迹是从 -536870912 开始递增,一直到 0;线程数量的变化轨迹是从0 开始递增,一直到 536870912
* 2. ctl直接等于 536870910,再定义两个线程,debug看效果 do it by practise
* </pre>
*
* <pre>
* ctl的初始值:-536870912
* ctl = ctlOf(RUNNING, 0): -536870912 -> 11100000000000000000000000000000 -> size: 32
* </pre>
*/
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// COUNT_BITS = 29
private static final int COUNT_BITS = Integer.SIZE - 3;
/**
* <pre>
* (1 << COUNT_BITS) = (1 << 29) -> 536870912 -> 100000000000000000000000000000 -> size: 30
* CAPACITY = ((1 << 29) - 1) -> 536870911 -> 11111111111111111111111111111 -> size: 29
* ~CAPACITY = ~((1 << 29) - 1) -> -536870912 -> 11100000000000000000000000000000 -> size: 32
* </pre>
*/
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
/**
* NOTE: 这几个状态值是有数值顺序的,所以这几个状态值才可以进行大于、小于等操作
*
* runState is stored in the high-order bits
* <pre>
* COUNT_BITS = 29
* RUNNING (-1 << 29): -536870912 -> 11100000000000000000000000000000 -> size: 32
* SHUTDOWN (0 << 29): 0 -> 0 -> -> size: 1
* STOP (1 << 29): 536870912 -> 100000000000000000000000000000 -> size: 30
* TIDYING (2 << 29): 1073741824 -> 1000000000000000000000000000000 -> size: 31
* TERMINATED (3 << 29): 1610612736 -> 1100000000000000000000000000000 -> size: 31
* </pre>
*
* 通过实践得出:这里的常量只是状态的边界值。换句话说,每个状态其实是一个范围,具体如下
* runState: ------- RUNNING -------- )[ ---------- SHUTDOWN --------- )[ ------------ STOP ---------- )[ ------------- TIDYING -------- )[ TERMINATED
* 11100000000000000000000000000000 ~ 0 ~ 100000000000000000000000000000 ~ 1000000000000000000000000000000 ~ 1100000000000000000000000000000 ~ 无穷
*/
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
状态方法
/**
* 这个方法:返回负数说明线程状态是RUNNING;返回0说明线程状态是SHUTDOWN;理论上不返回正数
*
* <pre>
* 由于
* ~CAPACITY = ~((1 << 29) - 1) -> -536870912 -> 11100000000000000000000000000000 -> size: 32
* ctl = ctlOf(RUNNING,0) -> -536870912 -> 11100000000000000000000000000000 -> size: 32
* 所以
* c=ctl时,ctl & ~CAPACITY -> -536870912 & -536870912 -> 11100000000000000000000000000000 = -536870912,
* 所以
* 随着ctl ++,runStateOf方法结果也是负数,并从-536870912开始递 +1,一直到 0,所以也可以是说负数表示线程状态是RUNNING(运行状态)时
*
* 举例:
* 当第一次ctl ++后,ctl -> -536870911 -> 11100000000000000000000000000001
* 此时,ctl & ~CAPACITY -> -536870911 & -536870912 -> 11100000000000000000000000000001 & 11100000000000000000000000000000
* NOTE: 当runStateOf等于0时,线程状态就变成了SHUTDOWN
* </pre>
*/
private static int runStateOf(int c) { return c & ~CAPACITY; }
/**
* <pre>
* 由于
* CAPACITY = (1 << 29) - 1 -> 536870911 -> 11111111111111111111111111111 -> size: 29
* ctl = ctlOf(RUNNING, 0) -> -536870912 -> 11100000000000000000000000000000 -> size: 32
* 所以
* c=ctl时,ctl & CAPACITY -> -536870912 & 536870911 -> 00000000000000000000000000000000 = 0
* 所以
* 随着ctl ++,所以workerCountOf方法结果从0开始递 +1,一直到 536870911
* </pre>
*/
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
线程池的执行过程,