Java线程池五种状态(RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED)通过ctl变量高3位编码,低29位存线程数;RUNNING(111)接收并处理任务,SHUTDOWN(000)拒新任务但处理队列,STOP(001)拒新任务、清队列、中断执行中任务,TIDYING(010)任务全终止且线程数为0时触发terminated(),TERMINATED(011)表示terminated()执行完毕、线程池彻底关闭。

线程池的五种状态(RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED)在 java.util.concurrent.ThreadPoolExecutor 中并不是用独立枚举值表示的,而是通过一个 32 位 int 类型的原子变量 ctl(control) 的高 3 位来编码状态,低 29 位记录当前活跃线程数。这种设计实现了状态与线程数的紧凑共存和原子更新。
ctl 的结构:高3位状态 + 低29位线程数
ThreadPoolExecutor 内部定义:
- COUNT_BITS = 29:表示用于存储工作线程数量的位数;
-
CAPACITY = (1 << COUNT_BITS) - 1,即
0x1FFFFFFF(29 个 1),是线程数的最大值; -
RUNNING = -1 << COUNT_BITS → 高 3 位为
111,即0xE0000000; - 其余状态依次递减,每次右移一位或按固定偏移设置,确保高 3 位唯一且可比较大小。
各状态的位模式与含义
所有状态值都以高 3 位为核心标识,具体如下:
-
RUNNING(111):
ctl = 0b11100000_00000000_00000000_00000000 = 0xE0000000。
接受新任务,也处理阻塞队列中的任务。 -
SHUTDOWN(000):
ctl = 0b00000000_00000000_00000000_00000000 = 0x00000000。
不接受新任务,但继续执行已提交和队列中的任务。 -
STOP(001):
ctl = 0b00100000_00000000_00000000_00000000 = 0x20000000。
不接受新任务,不处理队列任务,中断正在执行的线程。 -
TIDYING(010):
ctl = 0b01000000_00000000_00000000_00000000 = 0x40000000。
所有任务已终止,线程数为 0,即将进入终止清理阶段(调用terminated())。 -
TERMINATED(011):
ctl = 0b01100000_00000000_00000000_00000000 = 0x60000000。
终结完成,terminated()执行完毕,线程池彻底关闭。
状态判断与转换依赖位运算
由于状态藏在高 3 位,所有判断都需屏蔽低 29 位,提取状态码:
-
获取当前状态:
ctl & ~CAPACITY(即ctl & 0xE0000000); -
获取当前线程数:
ctl & CAPACITY; -
状态比较示例:
runStateAtLeast(ctl, SHUTDOWN)→(ctl & ~CAPACITY) >= SHUTDOWN;
runStateLessThan(ctl, STOP)→(ctl & ~CAPACITY) < STOP; - 状态变更使用
compareAndSet原子更新整个ctl值,例如从 RUNNING → SHUTDOWN 是将ctl从0xE0000000 + n改为0x00000000 + n(n 为原线程数)。
为什么用位运算而非枚举?
这种设计兼顾了性能、原子性与空间效率:
- 单个
volatile int即可承载状态+计数,避免多字段并发更新的复杂性; - 状态比较只需一次位与+整数比较,无分支预测开销;
- 状态自然有序(RUNNING > SHUTDOWN
- 线程数上限约 5.3 亿(2²⁹−1),远超实际需求,无溢出风险。

















