FutureTask没有COMPLETED状态,合法终态仅NORMAL(正常完成)和EXCEPTIONAL(异常完成);state为0~6的volatile int,共7种状态,isDone()在NORMAL、EXCEPTIONAL、CANCELLED时均返回true。

FutureTask 没有 COMPLETED 状态,这是常见误解。JDK 中定义的合法终态只有两个:NORMAL(正常完成)和 EXCEPTIONAL(异常完成)。
状态命名以源码为准,不存在 COMPLETED
FutureTask 内部使用 state 字段(int 类型)表示生命周期,其取值为 0~6,对应七种状态:
- NEW:初始状态,任务尚未执行
- COMPLETING:正在设置结果(outcome),是 NORMAL 或 EXCEPTIONAL 的过渡态
-
NORMAL:任务成功执行完毕,
outcome存储返回值 -
EXCEPTIONAL:任务执行中抛出未捕获异常,
outcome存储该Throwable - CANCELLED:任务被取消(未开始或已开始但未完成)
- INTERRUPTING:正尝试中断运行中的线程
- INTERRUPTED:中断操作已完成
注意:COMPLETED 并非 JDK 源码中的枚举值或常量名,也未出现在 FutureTask 的任何状态流转逻辑中。部分资料误将 NORMAL 和 EXCEPTIONAL 统称为“completed states”,但这只是语义归类,不是实际状态名。
NORMAL 与 EXCEPTIONAL 的触发条件明确
二者均由 run() 方法内部调用的底层方法决定:
立即学习“Java免费学习笔记(深入)”;
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 若
Callable.call()正常返回,则走set(result)→ 状态变为 NORMAL - 若
Callable.call()抛出未捕获异常,则走setException(ex)→ 状态变为 EXCEPTIONAL - 无论哪种终态,都会唤醒所有阻塞在
get()上的线程,并填充outcome字段
isDone() 返回 true 的三种情况
isDone() 是判断“是否已结束”的统一入口,它在以下任一状态下返回 true:
- 状态为 NORMAL(正常完成)
- 状态为 EXCEPTIONAL(异常完成)
- 状态为 CANCELLED(已被取消)
也就是说,isDone() 不区分成功或失败,只反映任务是否脱离活跃执行阶段。如需进一步判断结果性质,应配合 isCancelled() 和 get() 的异常捕获逻辑。
实际开发中如何区分 NORMAL 与 EXCEPTIONAL
不能依赖状态码直接比较(如 state == NORMAL),因为 state 是 package-private 字段,外部不可访问。推荐方式是:
- 调用
get()或get(timeout, unit) - 若返回值不为空 → 属于 NORMAL
- 若抛出
ExecutionException→ 原因即为getCause(),对应 EXCEPTIONAL - 若抛出
CancellationException→ 对应 CANCELLED
这种基于行为而非状态码的判断方式,既符合封装原则,也兼容 Future 接口契约。

















