FutureTask 的行为完全由 volatile int state 控制:state == NEW 时才执行 run();state < COMPLETING 时 get() 挂起,≥ COMPLETING 时自旋等待;cancel() 是否生效取决于 state 当前值;COMPLETING 瞬态插入内存屏障确保 outcome 原子可见。

因为 FutureTask 的所有行为——是否执行任务、能否取到结果、是否允许取消、线程为何挂起或唤醒——全部由 volatile int state 的取值和变更路径决定。它不是辅助标记,而是驱动整个生命周期的物理开关。
state 控制任务能否真正执行
run() 方法只有在 state == NEW 时才进入实际计算逻辑;一旦 CAS 成功将 state 改为 COMPLETING,就表示“任务体已开始收尾”,后续再调用 run() 直接返回。没有 state 的原子校验,多个线程反复调用 run() 就会导致重复执行。
- NEW → COMPLETING:是执行入口的唯一闸门
- 非 NEW 状态下调用 run() 不做任何事,保证幂等性
- 手动 new Thread(task).start() 或 submit() 触发 run(),本质都是在试探这个闸门
state 决定 get() 是立即返回还是挂起等待
get() 的阻塞/非阻塞行为完全取决于 state 当前值:
- state < COMPLETING(即仍为 NEW)→ 线程 park() 入队,等待唤醒
- state ≥ COMPLETING → 自旋等待终态(NORMAL/EXCEPTIONAL/CANCELLED),不返回也不抛异常
- state 达终态后,outcome 才被安全写入,get() 才能读到有效结果或异常
没有 state 的分级控制,就无法实现“无锁读取 + 安全阻塞”的组合效果。
state 是 cancel() 是否生效的判断依据
cancel(boolean mayInterruptIfRunning) 的语义差异,全靠 state 判断:
- state == NEW:可直接设为 CANCELLED,任务永不执行
- state == RUNNING(实际是 COMPLETING):mayInterruptIfRunning = true 才尝试 interrupt() 当前线程;false 则放任执行完
- state 已为终态:cancel() 返回 false,操作无效
它不是靠“有没有在跑”这种模糊判断,而是用精确的整数值做状态跃迁仲裁。
state 保障 outcome 写入的原子可见性
COMPLETING 这个瞬态的存在,就是为了插入一道内存屏障:
- 先写 outcome(使用 putOrderedInt,轻量但保证后续读可见)
- 再改 state 为 NORMAL 或 EXCEPTIONAL
- 这样并发 get() 线程看到终态时,outcome 必然已写好,不会读到未初始化值
跳过 COMPLETING 直接写 state,就会因指令重排或缓存不一致,导致结果字段读取错乱。

















