futuretask 的核心逻辑是将可返回结果的异步任务封装为“可执行+可查询+可取消”的统一对象:实现 runnable 和 future 接口,用 volatile state 管理状态,outcome 存结果或异常,get() 通过挂起-唤醒机制等待,cancel 支持中断运行中任务或仅取消未启动任务。

FutureTask 的核心逻辑是:把一个可返回结果的异步任务封装成“可执行 + 可查询 + 可取消”的统一对象,主线程提交后立即返回,不阻塞;真正耗时计算在后台线程完成;结果通过 get() 按需获取,未就绪时才阻塞。
它既是任务,又是结果容器
FutureTask 实现了 Runnable 和 Future 两个接口:
- 作为
Runnable,能被Thread或线程池直接执行; - 作为
Future,提供isDone()、cancel()、get()等方法控制生命周期和获取结果; - 内部用
volatile int state管理状态(NEW → COMPLETING → NORMAL/EXCEPTIONAL),确保线程安全; - 执行结果(或异常)存于
outcome字段,get()时直接读取,无需额外同步。
等待不是轮询,而是挂起+唤醒机制
调用 get() 时若任务未完成,当前线程不会空转,而是:
- 以 CAS 方式把自己加入
waiters链表(一个单向无锁链表); - 调用
LockSupport.park()主动挂起; - 当任务执行完毕(
set()或setException()),遍历waiters并对每个节点调用LockSupport.unpark()唤醒; - 被唤醒的线程重新检查状态,拿到结果后退出。
结果交付与异常处理一体化
FutureTask 把成功值和失败异常统一收口到 outcome 字段中:
- 正常完成:调用
set(V result),将结果赋值给outcome; - 执行出错:调用
setException(Throwable t),把异常包装为ExecutionException存入outcome; -
get()方法无论成功或失败,都只抛出标准异常(InterruptedException或ExecutionException),上层无需区分底层是 return 还是 throw。
取消操作具备语义分级能力
cancel(boolean mayInterruptIfRunning) 支持两种策略:
-
mayInterruptIfRunning = true:若任务正在运行,尝试中断执行线程(通过Thread.interrupt()); -
mayInterruptIfRunning = false:只取消尚未开始的任务,正在运行的任其自然结束; - 无论哪种,只要成功调用
cancel(),状态都会变为CANCELLED,后续get()直接抛出CancellationException。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











