JDK 8 FutureTask源码详解(详细注释版)

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并发编程中处理异步任务结果的核心工具,为开发者提供了强大而灵活的任务管理能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值