JDK 8 FutureTask源码详解(详细注释版)
1. FutureTask核心类源码
/*
* FutureTask是Future接口的基本实现
* 可以包装Callable或Runnable对象,使其具有Future的所有功能
* 因为实现了Runnable接口,所以可以提交给Executor执行
* 是Java并发编程中非常重要的工具类
*/
public class FutureTask<V> implements RunnableFuture<V> {
/*
* 内部状态定义
* 使用整数表示任务的不同状态,通过原子操作进行状态转换
*/
private volatile int state;
private static final int NEW = 0; // 新建状态,任务刚创建
private static final int COMPLETING = 1; // 完成中状态,任务正在设置结果
private static final int NORMAL = 2; // 正常完成状态,任务成功完成
private static final int EXCEPTIONAL = 3; // 异常完成状态,任务执行抛出异常
private static final int CANCELLED = 4; // 已取消状态,任务被取消
private static final int INTERRUPTING = 5; // 中断中状态,正在中断执行任务的线程
private static final int INTERRUPTED = 6; // 已中断状态,任务执行线程已被中断
/*
* 状态转换关系:
* NEW -> COMPLETING -> NORMAL (正常完成)
* NEW -> COMPLETING -> EXCEPTIONAL (异常完成)
* NEW -> CANCELLED (取消,不中断线程)
* NEW -> INTERRUPTING -> INTERRUPTED (取消,中断线程)
*/
// 底层任务,可以是Callable或Runnable
// 使用Callable统一处理Runnable和Callable
private Callable<V> callable;
// 任务结果或异常
// 对于正常结果:存储实际结果
// 对于异常结果:存储Throwable对象
private Object outcome; // non-volatile, protected by state reads/writes
// 执行任务的线程引用
// 用于取消时中断正在执行任务的线程
private volatile Thread runner;
// 等待线程栈
// 使用Treiber栈算法维护等待任务完成的线程列表
private volatile WaitNode waiters;
/**
* WaitNode内部类
* 用于维护等待线程的链表节点
* 实现了Treiber无锁栈算法
*/
static final class WaitNode {
volatile Thread thread; // 等待的线程
volatile WaitNode next; // 下一个等待节点
WaitNode() {
thread = Thread.currentThread();
}
}
/**
* 报告结果或抛出异常
* 根据当前状态返回结果或抛出相应异常
*
* @param s 当前任务状态
* @return 任务执行结果
* @throws ExecutionException 如果任务执行过程中抛出异常
* @throws CancellationException 如果任务被取消
*/
@SuppressWarnings("unchecked")
private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL) // 正常完成,返回结果
return (V)x;
if (s >= CANCELLED) // 被取消,抛出取消异常
throw new CancellationException();
// 异常完成,抛出执行异常包装原始异常
throw new ExecutionException((Throwable)x);
}
/**
* 构造方法 - 包装Callable对象
*
* @param callable 要包装的Callable对象
* @throws NullPointerException 如果callable为null
*/
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // 确保callable的可见性
}
/**
* 构造方法 - 包装Runnable对象和结果
* 内部将Runnable转换为Callable
*
* @param runnable 要包装的Runnable对象
* @param result 任务完成时返回的结果
* @throws NullPointerException 如果runnable为null
*/
public FutureTask(Runnable runnable, V result) {
// 使用Executors工具类将Runnable转换为Callable
this.callable = Executors.callable(runnable, result);
this.state = NEW; // 确保callable的可见性
}
/**
* 判断任务是否被取消
* 状态大于等于CANCELLED表示任务被取消
*
* @return 如果任务在正常完成前被取消,则返回true
*/
@Override
public boolean isCancelled() {
return state >= CANCELLED;
}
/**
* 判断任务是否已完成
* 状态不等于NEW表示任务已完成(正常、异常或取消)
*
* @return 如果任务已完成,则返回true
*/
@Override
public boolean isDone() {
return state != NEW;
}
/**
* 取消任务的执行
* 这是Future接口的核心方法之一
*
* @param mayInterruptIfRunning 如果执行该任务的线程应该被中断,则为true;
* 否则,已经开始执行的任务应该被允许完成
* @return 如果任务无法取消(通常是因为它已经正常完成),则返回false;否则返回true
*/
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
// 如果任务状态不是NEW或者CAS设置新状态失败,说明任务已完成或已取消
if (!(state == NEW &&
UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // 防止中断调用抛出异常
if (mayInterruptIfRunning) {
try {
Thread t = runner; // 获取执行任务的线程
if (t != null)
t.interrupt(); // 中断线程
} finally { // 设置最终状态
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
finishCompletion(); // 完成取消操作
}
return true;
}
/**
* 等待计算完成,然后获取其结果
* 这是Future接口的核心方法之一
*
* @return 计算结果
* @throws CancellationException 如果计算被取消
* @throws ExecutionException 如果计算抛出异常
* @throws InterruptedException 如果当前线程在等待时被中断
*/
@Override
public V get() throws InterruptedException, ExecutionException {
int s = state;
// 如果任务未完成(状态为NEW或COMPLETING),等待完成
if (s <= COMPLETING)
s = awaitDone(false, 0L); // 不带超时等待
return report(s); // 报告结果或异常
}
/**
* 等待计算完成,最多等待给定的时间,然后获取其结果(如果可用)
* 这是Future接口的核心方法之一
*
* @param timeout 等待的最长时间
* @param unit 时间单位
* @return 计算结果
* @throws CancellationException 如果计算被取消
* @throws ExecutionException 如果计算抛出异常
* @throws InterruptedException 如果当前线程在等待时被中断
* @throws TimeoutException 如果等待超时
*/
@Override
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (unit == null)
throw new NullPointerException();
int s = state;
// 如果任务未完成且等待超时后仍未完成,抛出超时异常
if (s <= COMPLETING &&
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
throw new TimeoutException();
return report(s);
}
/**
* 等待任务完成的核心方法
* 使用Treiber无锁栈算法实现高效的线程等待
*
* @param timed 是否启用超时控制
* @param nanos 等待时间(纳秒),仅在timed为true时有效
* @return 任务完成时的状态
* @throws InterruptedException 如果等待时被中断
*/
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
final long deadline = timed ? System.nanoTime() + nanos : 0L; // 计算截止时间
WaitNode q = null; // 等待节点
boolean queued = false; // 是否已入队
for (;;) { // 自旋等待
// 如果当前线程被中断,移除等待节点并抛出中断异常
if (Thread.interrupted()) {
removeWaiter(q); // 移除等待节点
throw new InterruptedException();
}
int s = state;
// 如果任务已完成(状态大于COMPLETING),返回状态
if (s > COMPLETING) {
if (q != null)
q.thread = null; // 清理线程引用
return s;
}
// 如果任务正在完成中(COMPLETING状态),让出CPU时间片
else if (s == COMPLETING) // 不能超时
Thread.yield();
// 如果还没有创建等待节点,创建一个
else if (q == null)
q = new WaitNode();
// 如果还没有入队,将等待节点加入等待队列
else if (!queued)
queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
q.next = waiters, q);
// 如果启用了超时控制,检查是否超时
else if (timed) {
nanos = deadline - System.nanoTime(); // 计算剩余时间
if (nanos <= 0L) { // 超时
removeWaiter(q); // 移除等待节点
return state;
}
// 阻塞指定时间
LockSupport.parkNanos(this, nanos);
}
// 否则阻塞等待
else
LockSupport.park(this);
}
}
/**
* 移除等待节点
* 用于清理被中断的等待线程或超时的等待线程
*
* @param node 要移除的节点
*/
private void removeWaiter(WaitNode node) {
if (node != null) {
node.thread = null; // 清理线程引用
retry:
for (;;) { // 重启以处理竞争条件
for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
s = q.next;
if (q.thread != null) // 节点有效
pred = q;
else if (pred != null) { // 节点无效,需要移除
pred.next = s;
if (pred.thread == null) // 检查竞争
continue retry;
}
// 头节点被移除,CAS更新头节点
else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
q, s))
continue retry;
}
break;
}
}
}
/**
* 任务执行完成后的清理工作
* 唤醒所有等待的线程
*/
private void finishCompletion() {
// assert state > COMPLETING;
for (WaitNode q; (q = waiters) != null;) {
// CAS设置waiters为null,确保只执行一次
if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
for (;;) { // 唤醒所有等待线程
Thread t = q.thread;
if (t != null) {
q.thread = null;
LockSupport.unpark(t); // 唤醒线程
}
WaitNode next = q.next;
if (next == null)
break;
q.next = null; // 断开链接帮助GC
q = next;
}
break;
}
}
done(); // 调用钩子方法
callable = null; // 减少内存占用
}
/**
* 钩子方法,在任务完成后调用
* 可以被子类重写以执行自定义的完成操作
*/
protected void done() { }
/**
* 设置任务结果
* 在任务正常完成后调用
*
* @param v 任务结果
*/
protected void set(V v) {
// CAS将状态从NEW设置为COMPLETING
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = v; // 设置结果
// 设置最终状态为NORMAL(使用putOrderedInt确保内存可见性)
UNSAFE.putOrderedInt(this, stateOffset, NORMAL);
finishCompletion(); // 完成操作
}
}
/**
* 设置任务异常
* 在任务执行抛出异常时调用
*
* @param t 任务异常
*/
protected void setException(Throwable t) {
// CAS将状态从NEW设置为COMPLETING
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = t; // 设置异常
// 设置最终状态为EXCEPTIONAL
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL);
finishCompletion(); // 完成操作
}
}
/**
* 执行任务的核心方法
* 实现了Runnable接口,是任务执行的入口点
* 这是FutureTask最重要的方法
*/
@Override
public void run() {
// 如果任务状态不是NEW或者无法设置runner线程,直接返回
// 防止任务重复执行
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
// 再次检查状态和callable,防止竞争条件
if (c != null && state == NEW) {
V result;
boolean ran;
try {
// 执行任务
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
// 设置异常结果
setException(ex);
}
if (ran)
// 设置正常结果
set(result);
}
} finally {
// runner必须为非null,直到状态被完成保护
runner = null;
// state必须在清空runner后读取,以防泄漏
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
/**
* 执行任务并重置状态
* 主要用于ScheduledThreadPoolExecutor中的周期性任务
* 执行完成后不改变任务状态,可以重复执行
*
* @return 如果任务正常执行完成,则返回true
*/
protected boolean runAndReset() {
// 状态检查和线程设置,防止重复执行
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return false;
boolean ran = false;
int s = state;
try {
Callable<V> c = callable;
// 检查callable和状态
if (c != null && s == NEW) {
try {
c.call(); // 执行任务但不设置结果
ran = true;
} catch (Throwable ex) {
ran = false;
setException(ex); // 设置异常
}
}
} finally {
runner = null; // 清理runner引用
s = state; // 重新读取状态
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
return ran && s == NEW; // 只有在正常执行且状态未改变时返回true
}
/**
* 处理可能的取消中断
* 在任务被取消且需要中断执行线程时调用
*
* @param s 当前状态
*/
private void handlePossibleCancellationInterrupt(int s) {
// 在中断者和取消者之间进行二次检查
if (s == INTERRUPTING)
while (state == INTERRUPTING)
Thread.yield(); // 等待中断完成
}
/*
* Unsafe操作相关字段和静态初始化块
* 用于高性能的原子操作
*/
private static final sun.misc.Unsafe UNSAFE;
private static final long stateOffset; // state字段的偏移量
private static final long runnerOffset; // runner字段的偏移量
private static final long waitersOffset; // waiters字段的偏移量
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> k = FutureTask.class;
stateOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("state"));
runnerOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("runner"));
waitersOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("waiters"));
} catch (Exception e) {
throw new Error(e);
}
}
}
2. RunnableFuture接口源码
/*
* RunnableFuture接口继承了Runnable和Future接口
* 表示既可运行又可获取结果的Future
* FutureTask实现了这个接口
*/
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* 将此Future设置为其计算结果,除非已被取消
* 这个方法来自Runnable接口,是任务执行的入口点
*/
void run();
}
3. 使用示例
/**
* FutureTask使用示例
*/
public class FutureTaskExample {
public static void main(String[] args) {
// 示例1:包装Callable
Callable<Integer> callableTask = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println("Task started in thread: " +
Thread.currentThread().getName());
Thread.sleep(2000); // 模拟耗时操作
return 42;
}
};
FutureTask<Integer> futureTask1 = new FutureTask<>(callableTask);
// 直接执行
Thread thread1 = new Thread(futureTask1);
thread1.start();
try {
// 检查任务状态
System.out.println("Task done: " + futureTask1.isDone());
System.out.println("Task cancelled: " + futureTask1.isCancelled());
// 获取结果(阻塞等待)
Integer result = futureTask1.get();
System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// 示例2:包装Runnable
Runnable runnableTask = new Runnable() {
@Override
public void run() {
System.out.println("Runnable task executed");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
};
// 指定结果
FutureTask<String> futureTask2 = new FutureTask<>(runnableTask, "Task Completed");
Thread thread2 = new Thread(futureTask2);
thread2.start();
try {
String result = futureTask2.get();
System.out.println("Runnable result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// 示例3:取消任务
FutureTask<Long> cancellableTask = new FutureTask<>(new Callable<Long>() {
@Override
public Long call() throws Exception {
for (int i = 0; i < 10; i++) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("Task was interrupted");
return -1L;
}
System.out.println("Working... " + i);
Thread.sleep(500);
}
return System.currentTimeMillis();
}
});
Thread thread3 = new Thread(cancellableTask);
thread3.start();
try {
Thread.sleep(1500); // 让任务运行一段时间
boolean cancelled = cancellableTask.cancel(true); // 取消并中断
System.out.println("Task cancelled: " + cancelled);
System.out.println("Task done: " + cancellableTask.isDone());
System.out.println("Task cancelled: " + cancellableTask.isCancelled());
// 尝试获取结果(会抛出CancellationException)
try {
Long result = cancellableTask.get();
System.out.println("Result: " + result);
} catch (CancellationException e) {
System.out.println("Task was cancelled");
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
/**
* 自定义FutureTask示例
*/
class CustomFutureTask<V> extends FutureTask<V> {
private final String taskName;
private long startTime;
private long endTime;
public CustomFutureTask(Callable<V> callable, String taskName) {
super(callable);
this.taskName = taskName;
}
@Override
public void run() {
System.out.println("Starting task: " + taskName);
startTime = System.currentTimeMillis();
super.run();
}
@Override
protected void done() {
endTime = System.currentTimeMillis();
System.out.println("Task " + taskName + " completed in " +
(endTime - startTime) + " ms");
if (isCancelled()) {
System.out.println("Task " + taskName + " was cancelled");
}
}
public long getExecutionTime() {
return endTime - startTime;
}
}
/**
* 自定义FutureTask使用示例
*/
class CustomFutureTaskExample {
public static void main(String[] args) {
CustomFutureTask<Integer> customTask = new CustomFutureTask<>(
new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(2000);
return 100;
}
},
"CustomTask"
);
Thread thread = new Thread(customTask);
thread.start();
try {
Integer result = customTask.get();
System.out.println("Result: " + result);
System.out.println("Execution time: " + customTask.getExecutionTime() + " ms");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
4. 核心设计要点总结
4.1 状态机设计
- 使用7种状态精确描述任务生命周期
- 通过CAS操作保证状态转换的原子性
- 状态转换图清晰,避免状态混乱
4.2 高效的等待机制
- 使用Treiber无锁栈算法维护等待线程
- LockSupport.park/unpark实现线程阻塞和唤醒
- 支持带超时的等待操作
4.3 线程安全保证
- volatile关键字保证字段可见性
- CAS操作保证原子性
- 合理的内存屏障使用
4.4 异常处理机制
- 区分正常完成、异常完成和取消三种情况
- 提供详细的异常信息传递
- 支持任务取消时的线程中断
4.5 内存管理优化
- 及时清理无用的线程引用
- 断开链表链接帮助垃圾回收
- 减少对象内存占用
4.6 扩展性设计
- 提供protected方法供子类重写
- done()钩子方法支持自定义完成操作
- runAndReset()支持周期性任务
4.7 性能优化
- 无锁算法减少竞争
- 局部变量缓存提高访问效率
- 合理的自旋和阻塞策略
FutureTask通过这些精心设计,成为了Java并发编程中处理异步任务结果的核心工具,为开发者提供了强大而灵活的任务管理能力。