线程池ctl变量
线程池,首先要搞明白一点:
线程池的
工作线程数量 workerCount 有效线程数量
和
线程池的状态 runState
是用一个 AtomicInteger 来标识的。
很多地方 都 根据 workerCount 和 runState 做 逻辑判断,所以,如果不搞懂这两,那看源码根本就看不懂。
workerCount 最大目前是 (2^29)-1 (about 500 million)
runState:
RUNNING: 线程池创建后的 默认状态,标识可以 接收 任务 和 处理 队列中的 任务
SHUTDOWN: 线程池 不 接收 新任务, 但是 队列已有的任务 会处理完
STOP: 线程池 不接收 新任务,不执行 队列中的任务, 中断 正在执行的任务
TIDYING: 所有的任务 已经 终止, workerCount 为 0, 执行 terminated() hook method
TERMINATED: terminated() 执行完毕
线程池主要就是 :
1. 接收任务,并执行任务
2. 处理 队列中的任务
3. 任务执行中
那总结一下 runState:
第一: 只有 RUNNING 状态,标识 线程池 正常,接收、处理、执行都可以
第二:SHUTDOWN STOP
这两种状态,标识 当前线程池 需要被回收了,但是 回收策略不一样:
首先,都表示 线程池 不再接收任务
其次,已经接收的任务 怎么处理:
SHUTDOWN :表示 把剩下的工作作完,也就是 已接收的任务 会处理完毕
STOP: 表示 撂挑子了,即使已经接收的任务 也不继续处理,并且 正在执行的任务 也要中断
可见:
SHUTDOWN 比较缓和,会进行收尾
STOP 比较激进,马上就不工作了
第三:TIDYING TERMINATED
这两种状态 是再 第二种状态 后设置的,进行最后的处理
状态转换图如下:
runStatus和workerCount
// ctl初始值,高三位 101 低29位全部为0
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// 值为 29
private static final int COUNT_BITS = Integer.SIZE - 3;
// int型的状态,都是 左移 29位,也就是说, 状态 变量 高三位表示状态,低29为全部为0
// runState is stored in the high-order bits
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;
// 二进制为:00011111 11111111 11111111 11111111 , 即 高三位 为 0,低29位为 1
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// 按位与 & : 11 =》 1
// unpacking ctl
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
// | 按位或 01/ 10/ 11 =》1
// Packing ctl, 是 根据 runState 和 workerCount 计算出 ctl 的最新值
private static int ctlOf(int rs, int wc) { return rs | wc; }
// shutdown 和 shutdownNow 两个方法,在修改 线程池状态时调用该方法
// targetState 为 SHUTDOWN或者STOP
private void advanceRunState(int targetState) {
for (;;) {
int c = ctl.get();
// 如果 修改为 SHUTDOWN,而此时 状态为 SHUTDOWN 、STOP 、TIDYING、TERMINATED
// 如果 修改为 STOP,而此时状态为 STOP 、TIDYING、TERMINATED
// 那么,则直接返回
if (runStateAtLeast(c, targetState) ||
// cas 执行,将 状态修改为 目标状态
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}