Future源码阅读

FutureTask是Java并发编程中一个重要的组件,它实现了Runnable和Future接口,允许我们执行异步任务并获取结果。本文详细介绍了FutureTask的内部实现,包括任务状态管理、取消操作、获取结果的方法以及其在并发环境中的使用。通过对FutureTask的源码分析,我们可以更好地理解和使用这个强大的工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Future
public interface Future<V> {

  	// 取消任务,返回true,则isCancelled和isDone都返回true
  	// 参数:true表示如果任务在执行则中断它;false表示如果任务在执行,则取消它。
  	// 返回是否取消成功。
    boolean cancel(boolean mayInterruptIfRunning);

    boolean isCancelled();

    boolean isDone();
  
 		// get操作是一个阻塞操作
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
RunnableFuture

RunnableFuture继承Runnable,实现Future接口

public interface RunnableFuture<V> extends Runnable, Future<V> {

    void run();
}
FutureTask
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; // 已经中断

  	// FutureTask封装了Callable
    private Callable<V> callable;
  	// 返回值(可以是一个异常类)
    private Object outcome; // non-volatile, protected by state reads/writes
    private volatile Thread runner;
  	// 任务等待队列
    private volatile WaitNode waiters;

  	// 根据状态返回值,state=NORMAL才返回值,其他都抛出异常
    @SuppressWarnings("unchecked")
    private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL) // MORMAL 成功
            return (V)x;
        if (s >= CANCELLED) // >=CANCELLED,取消或中断
            throw new CancellationException();
        throw new ExecutionException((Throwable)x); // 其他情况,NEW/COMPLETING/EXCEPTIONAL则抛出异常
    }

    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable; // 封装callable
        this.state = NEW; // 初始状态NEW
    }

  	// Executors.callable返回一个RunnableAdapter对象,这个对象其实就是一个封装了Runnable和V的Callable,我理解就是把Runnable转Callable
    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;
    }

  	// 是否取消,CANCELLED|INTERRUPTING|INTERRUPTED
    public boolean isCancelled() {
        return state >= CANCELLED;
    }

  	// 是否结束,只要不是NEW,就已经结束
    public boolean isDone() {
        return state != NEW;
    }

  	// 取消操作,mayInterruptIfRunning决定是中断(中断也是取消的一种)还是取消
    public boolean cancel(boolean ,mayInterruptIfRunning) {
      	// 如果任务状态不是new或者设置取消状态失败(根据参数决定),则返回false,表示取消不成功
        if (!(state == NEW &&
              UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
                  mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
            return false;
      	// 走到这里说明,任务状态为mayInterruptIfRunning ? INTERRUPTING : CANCELLED
        try {    // in case call to interrupt throws exception
            if (mayInterruptIfRunning) {
              	// 任务在跑,此时状态为INTERRUPTING,是一个中间态
                try {
                    Thread t = runner;
                    if (t != null)
                        t.interrupt(); // 中断
                } finally { // final state
                  	// 设置为已中断INTERRUPTED
                    UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                }
            }
        } finally {
          	// 收尾工作
            finishCompletion();
        }
      	// 返回取消成功
        return true;
    }

    // 任务状态<=COMPLETING(COMPLETING是一个中间态,查看report代码可知只有在NORMAL才有值),则等待。
    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L); // 返回任务状态
        return report(s); // 根据状态获取返回值
    }

    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);
    }

    protected void done() { }

  	// 任务状态设置为中间态COMPLETING,然后最终状态为NORMAL
    protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion(); // 收尾工作
        }
    }

  	// 任务状态设置为中间态COMPLETING,然后最终状态为EXCEPTIONAL
    protected void setException(Throwable t) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = t; // outcome也可以是一个异常类
            UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
            finishCompletion(); // 收尾工作
        }
    }

  	// 任务的执行入口
    public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
          	// 如果任务状态不是NEW或者,CAS runnerOffset=当前线程失败(其实本质上修改的是runner),则直接返回
            return;
        try {
          	// 走到这里runner肯定=Thread.currentThread()
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                // 任务状态是NEW且callable非空,才走这里
                V result;
                boolean ran;
                try {
                    result = c.call(); // 执行callable.call方法,会拿到返回值
                    ran = true; // 设置状态为已经跑成功
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                  	// 如果跑失败,则设置状态为EXCEPTIONAL
                    setException(ex);
                }
                if (ran)
                  	// 如果任务跑成功后,就设置状态为NORMAL
                    set(result);
            }
        } finally {
            runner = null; // runner置空
            int s = state;
            if (s >= INTERRUPTING) // 如果是中断状态,则处理中断
                handlePossibleCancellationInterrupt(s);
        }
    }
  
    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;
            if (c != null && s == NEW) {
                try {
                    c.call(); // don't set result
                    ran = true;
                } catch (Throwable ex) {
                    setException(ex);
                }
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
        return ran && s == NEW;
    }

  	// 如果是中断状态,则当前线程让出执行权,直到其他线程修改了当前线程的状态。
    private void handlePossibleCancellationInterrupt(int s) {
        if (s == INTERRUPTING)
            while (state == INTERRUPTING)
                Thread.yield();
    }

  	// 线程等待队列。
    static final class WaitNode {
        volatile Thread thread;
        volatile WaitNode next;
        WaitNode() { thread = Thread.currentThread(); }
    }

  	// 收尾操作,cancel/set/setException都会最后调用
    // 遍历线程等待队列,然后挨个唤醒(unpark),什么时候阻塞呢?在get时不是调用了awaitDone吗。
    private void finishCompletion() {
        // assert state > COMPLETING;
        for (WaitNode q; (q = 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; // unlink to help gc
                    q = next;
                }
                break;
            }
        }

        done();

        callable = null;  // callable置空      // to reduce footprint
    }

    // 本方法有一个死循环,首先WaitNode为空,经过第一次循环后,初始化一个WaitNode对象出来;
  	// 接着第二次循环,把当前任务放到等待队列头部
  	// 接下来的循环,当前任务要么执行完成返回状态,要么被其他线程中断,要么因为超时而返回状态
    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;
            if (s > COMPLETING) {
              	// 如果已经完成(成功、中断、取消),则返回状态
                if (q != null)
                    q.thread = null;
                return s;
            }
            else if (s == COMPLETING) // cannot time out yet
              	// 如果处于中间状态,则挂起线程
                Thread.yield();
            else if (q == null)
              	// 初始化WaitNode
                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);
        }
    }

    private void removeWaiter(WaitNode node) {
        if (node != null) {
            node.thread = null;
            retry:
            for (;;) {          // restart on removeWaiter race
                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) // check for race
                            continue retry;
                    }
                    else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                          q, s))
                        continue retry;
                }
                break;
            }
        }
    }

  	// 操作这些offSet对象等同于操作state/runner/waiters
    private static final sun.misc.Unsafe UNSAFE;
    private static final long stateOffset;
    private static final long runnerOffset;
    private static final long waitersOffset;
    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);
        }
    }

}
总结

FutureTask实现了run方法,当线程启动时,会去调用run方法。在run方法中,又调用了callable的call方法去获取返回值。

当我们调用get方法时,run方法可能还没执行完毕,所以get方法必须阻塞等待。那么什么时候退出阻塞状态呢?线程的状态为结束(成功/中断/取消),或者被中断,或者超时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值