1、线程池中基本属性和方法源码解析
2、线程池的五种状态变换源码分析
3、线程池添加线程源码解析
4、线程池线程运行执行任务源码解析
5、线程池shutdown源码解析
6、线程池中线程退出机制源码解析
线程池源码的基础属性和方法
在线程池的源码中,会通过一个AtomicInteger类型的变量
ctl
,来表示
线程池的状态
和
当前线程池中
的工作线程数量
。
一个Integer占4个字节,也就是32个bit,
线程池有5个状态:
1. RUNNING
2. SHUTDOWN
3. STOP
4. TIDYING
5. TERMINATED
2个bit能表示4种状态,那5种状态就至少需要三个bit位,比如在线程池的源码中就是这么来表示的:
private static final int COUNT_BITS = Integer.SIZE - 3;
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;
Integer.SIZE为32,所以COUNT_BITS为29,最终各个状态对应的二级制为:
1. RUNNING:
111
00000 00000000 00000000 00000000
2. SHUTDOWN:
000
00000 00000000 00000000 00000000
3. STOP:
001
00000 00000000 00000000 00000000
4. TIDYING:
010
00000 00000000 00000000 00000000
5. TERMINATED:
011
00000 00000000 00000000 00000000
所以,只需要使用一个Integer数字的
最高三个bit
,就可以
表示5种线程池的状态
,而
剩下的29个bit
就 可以用来
表示工作线程数
,比如,假如ctl为:
111
00000 00000000 00000000 0000
1
0
1
0,就表示 线程池的状态为RUNNING,线程池中目前在工作的线程有10个,这里说的“在工作”意思是线程活着,要么在执行任务,要么在阻塞等待任务。
同时,在线程池中也提供了一些方法用来获取线程池状态和工作线程数,比如:
// 29,二进制为00000000 00000000 00000000 00011101
private static final int COUNT_BITS = Integer.SIZE - 3;
// 00011111 11111111 11111111 11111111
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// ~CAPACITY为11100000 00000000 00000000 00000000
// &操作之后,得到就是c的高3位
private static int runStateOf(int c) {
return c & ~CAPACITY;
}
// CAPACITY为00011111 11111111 11111111 11111111
// &操作之后,得到的就是c的低29位
private static int workerCountOf(int c) {
return c & CAPACITY;
}
同时,还有一个方法:
private static int ctlOf(int rs, int wc) {
return rs | wc;
}
就是用来把运行状态和工作线程数量进行合并的一个方法,不过传入这个方法的两个int数字有限制, rs的低29位都得为0,wc的高3位都得为0,这样经过或运算之后,才能得到准确的ctl。
同时,还有一些相关的方法:
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;
// c状态是否小于s状态,比如RUNNING小于SHUTDOWN
private static boolean runStateLessThan(int c, int s) {
return c < s;
}
// c状态是否大于等于s状态,比如STOP大于SHUTDOWN
private static boolean runStateAtLeast(int c, int s) {
return c >= s;
}
// c状态是不是RUNNING,只有RUNNING是小于SHUTDOWN的
private static boolean isRunning(int c) {
return c < SHUTDOWN;
}
// 通过cas来增加工作线程数量,直接对ctl进行加1
// 这个方法没考虑是否超过最大工作线程数的(2的29次方)限制,源码中在调用该方法之前会进行判断的
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
// 通过cas来减少工作线程数量,直接对ctl进行减1
private boolean compareAndDecrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect - 1);
}
前面说到线程池有5个状态,这5个状态分别表示:
1. RUNNING:
线程池正常运行中,可以正常的接受并处理任务.
2. SHUTDOWN
:线程池关闭了,
不能接受新任务