Java线程池用AtomicInteger ctl变量高位3位存运行状态、低位29位存线程数,采用左移+按位或编码,如RUNNING为-1,共支持5种状态和超5亿线程数。

Java 线程池用一个 AtomicInteger ctl 变量,通过高位二进制位统一管理运行状态和线程数量,核心是「3 位状态 + 29 位计数」的紧凑编码设计,既节省内存又支持原子操作。
ctl 的二进制布局:高 3 位存状态,低 29 位存线程数
ctl 是一个 32 位整数,其中:
- 高 3 位(bit 31–29)表示线程池当前运行状态,共 5 种状态,只需 3 bit 就能完整编码(2³ = 8 ≥ 5)
- 低 29 位(bit 28–0)表示当前活跃工作线程数(workerCount),理论最大值为 2²⁹ − 1 = 536,870,911
- 这种拆分不是字符串拼接,而是通过左移+按位或组合:例如
RUNNING | 3得到0b11100000_00000000_00000000_00000011
五种状态在高位的二进制表示
所有状态都由 COUNT_BITS = 29 左移生成,确保只影响高 3 位:
- RUNNING:-1 111(补码表示,值为 -536870912)
- SHUTDOWN:0 000(值为 0)
- STOP:1 001(值为 536870912)
- TIDYING:2 010(值为 1073741824)
- TERMINATED:3 011(值为 1610612736)
注意:状态值本身不包含线程数,只是“模板”;真正运行时的 ctl 值是状态模板与线程数按位或的结果。
立即学习“Java免费学习笔记(深入)”;
如何从 ctl 中安全分离状态和线程数
读取时靠两个掩码常量无损提取:
-
取状态:
runStateOf(c) = c & ~CAPACITY,其中CAPACITY = 0x1FFFFFFF(29 个低位 1),~CAPACITY = 0xE0000000(高 3 位 1,其余为 0) -
取线程数:
workerCountOf(c) = c & CAPACITY,直接屏蔽高 3 位,保留低 29 位数值 - 这两个操作都是纯位运算,零开销、无锁、线程安全,适合高频状态判断场景
状态流转为什么必须单向且不可逆
高位编码天然支持状态比较和原子跃迁:
- 状态值大小顺序与生命周期一致:
RUNNING < SHUTDOWN < STOP < TIDYING < TERMINATED - 状态变更通过 CAS 比较并设置新 ctl 值实现,例如从 RUNNING → SHUTDOWN,需确保原 ctl 高 3 位确实是
111 - 因高位固定、低位独立,状态升级(如 SHUTDOWN → STOP)可直接替换高 3 位,无需关心当前线程数,逻辑清晰且不易出错


















