futuretask 通过 volatile int state 管理7种单向流转状态,isdone()判断是否结束(normal/exceptional/cancelled),iscancelled()仅对成功取消返回true,get()阻塞获取结果或抛异常,非阻塞检查可用isdone()结合get(0, timeunit)或升级为completablefuture。

FutureTask 本身不主动检查状态,而是通过其继承的 Future 接口方法来**获取和响应**任务当前所处的状态。它的状态检查是被动、同步且线程安全的,核心在于理解其内部状态机和对应方法的行为逻辑。
状态由 volatile int 控制,共 7 种内部状态
FutureTask 内部用一个 volatile int state 字段表示任务生命周期,包括:NEW(初始)、COMPLETING(完成中)、NORMAL(正常结束)、EXCEPTIONAL(异常结束)、CANCELLED(已取消)、INTERRUPTING(中断中)、INTERRUPTED(已中断)。这些状态单向流转,不可逆。你无法直接读取 state 值,但所有公开方法(如 isDone()、isCancelled()、get())都基于它做判断。
常用状态检查方法及实际含义
- isDone():返回 true 表示任务已结束——即处于 NORMAL、EXCEPTIONAL 或 CANCELLED 中任一状态。注意:它不区分成功、失败或取消,只说明“不再运行”。
- isCancelled():仅当任务被 cancel(true) 或 cancel(false) 成功调用后返回 true(且状态变为 CANCELLED 或 INTERRUPTED)。即使任务已运行完,该方法也返回 false。
- get() / get(long, TimeUnit):这是最常用的“状态+结果”组合操作。若任务未完成,调用线程会阻塞;若已完成,立即返回结果或抛出 ExecutionException(封装异常)/ CancellationException。超时版本会在超时后抛出 TimeoutException。
如何在不阻塞的前提下安全检查执行进度
不能靠轮询 isDone() 来“监控进度”,因为 FutureTask 不提供运行中(RUNNING)状态暴露,也不支持回调或进度通知。它只支持“是否结束”这一二元判断。若需非阻塞检查:
- 调用 isDone() 判断是否结束,再决定是否调用 get() 获取结果(避免无谓阻塞);
- 使用 get(0, TimeUnit.SECONDS) 实现“立即尝试获取”,它会在任务未完成时立刻抛出 TimeoutException,可捕获后继续其他逻辑;
- 若需真正异步响应(如任务完成时触发动作),应配合 ExecutorService.submit() 返回的 FutureTask,再用额外线程轮询 + sleep,或升级为 CompletableFuture(支持 thenApply、whenComplete 等回调)。
cancel() 的状态影响需特别注意
调用 cancel(boolean mayInterruptIfRunning) 并不保证任务一定停止:
- 若任务尚未开始,会直接进入 CANCELLED 状态,isCancelled() 和 isDone() 均返回 true;
- 若任务正在运行,mayInterruptIfRunning = true 会尝试对执行线程调用 interrupt(),但任务是否响应中断、何时退出,取决于任务自身逻辑;
- 即使 cancel() 返回 true,也不能认为任务已终止——它可能仍在执行中(状态为 INTERRUPTING/INTERRUPTED),isDone() 此时仍为 false,直到真正结束。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











