资料内容:
线程池源码的基础属性和方法
在线程池的源码中,会通过一个AtomicInteger类型的变量ctl,来表示线程池的状态和当前线程池中
的工作线程数量。
一个Integer占4个字节,也就是32个bit,线程池有5个状态:
1. RUNNING
2. SHUTDOWN
3. STOP
4. TIDYING
5. TERMINATED
2个bit能表示4种状态,那5种状态就至少需要三个bit位,比如在线程池的源码中就是这么来表示的:
1 private static final int COUNT_BITS = Integer.SIZE - 3;
2
3 private static final int RUNNING = -1 << COUNT_BITS;
4 private static final int SHUTDOWN = 0 << COUNT_BITS;
5 private static final int STOP = 1 << COUNT_BITS;
6 private static final int TIDYING = 2 << COUNT_BITS;
7 private static final int TERMINATED = 3 << COUNT_BITS;
Integer.SIZE为32,所以COUNT_BITS为29,最终各个状态对应的二级制为:
1. RUNNING:11100000 00000000 00000000 00000000
2. SHUTDOWN:00000000 00000000 00000000 00000000
3. STOP:00100000 00000000 00000000 00000000
4. TIDYING:01000000 00000000 00000000 00000000
5. TERMINATED:01100000 00000000 00000000 00000000
所以,只需要使用一个Integer数字的最高三个bit,就可以表示5种线程池的状态,而剩下的29个bit就
可以用来表示工作线程数,比如,假如ctl为:11100000 00000000 00000000 00001010,就表示
线程池的状态为RUNNING,线程池中目前在工作的线程有10个,这里说的“在工作”意思是线程活
着,要么在执行任务,要么在阻塞等待任务。
同时,在线程池中也提供了一些方法用来获取线程池状态和工作线程数,比如:
1 // 29,二进制为00000000 00000000 00000000 00011101
2 private static final int COUNT_BITS = Integer.SIZE - 3;
3
4 // 00011111 11111111 11111111 11111111
5 private static final int CAPACITY = (1 << COUNT_BITS) - 1;
6
7 // ~CAPACITY为11100000 00000000 00000000 00000000
8 // &操作之后,得到就是c的高3位
9 private static int runStateOf(int c) {
10 return c & ~CAPACITY;
11 }
12
13 // CAPACITY为00011111 11111111 11111111 11111111
14 // &操作之后,得到的就是c的低29位
15 private static int workerCountOf(int c) {
16 return c & CAPACITY;
17 }
同时,还有一个方法:
1 private static int ctlOf(int rs, int wc) {
2 return rs | wc;
3 }
就是用来把运行状态和工作线程数量进行合并的一个方法,不过传入这个方法的两个int数字有限制,
rs的低29位都得为0,wc的高3位都得为0,这样经过或运算之后,才能得到准确的ctl。