Future详解( 二 )

3)核心方法
1.run()方法
public void run() {if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread()))return;// 只有当任务状态为new并且runner旧值为null才会执行到这里try {Callable<V> c = callable;if (c != null && state == NEW) {V result;boolean ran;try {// 调用callable.run()并返回结果result = c.call();ran = true;} catch (Throwable ex) {result = null;ran = false;setException(ex);}if (ran)// 内部设置outcome为callable执行的结果,并且更新任务的状态为NORMAL(任务正常执行)并且唤醒阻塞的线程set(result);}} finally {runner = null;int s = state;if (s >= INTERRUPTING)// 如果当前任务处于中断中,则执行这个方法线程会不断让出cpu直到任务处于已中断状态handlePossibleCancellationInterrupt(s);}}2.set(V v)方法
protected void set(V v) {if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {// 设置outcome(结果)为callable.run()返回的结果outcome = v;//修改状态UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state// 唤醒调用get()的所有等待的线程并清空栈finishCompletion();}}protected void setException(Throwable t) {if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {// 设置outcome(结果)为callable.run()抛出的异常outcome = t;UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final statefinishCompletion();}}3.get()方法
public V get() throws InterruptedException, ExecutionException {int s = state;// 条件成立会调用awaitDone方法自旋等待直到任务完成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);}//这个方法是真正用来获取任务的返回结果的 , 这个方法在get()方法里面会被调用,如果该方法被调用,说明任务已经执行完了 。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);}4.awaitDone(boolean timed, long nanos)方法
// 这个方法的作用是等待任务被完成(正常完成或出现异常完成都算完成),被中断,或是被超时private int awaitDone(boolean timed, long nanos)throws InterruptedException {final long deadline = timed ? System.nanoTime() + nanos : 0L;WaitNode q = null;boolean queued = false;for (;;) {// 如果当前线程出现中断异常,则将该线程代表的WaitNode结点移出栈并抛出中断异常if (Thread.interrupted()) {removeWaiter(q);throw new InterruptedException();}int s = state;// 如果当前任务状态大于COMPLETING,说明当前任务已经有结果了(任务完成、中断、取消),直接返回任务状态if (s > COMPLETING) {if (q != null)q.thread = null;return s;}// 当前任务处于临界状态 , 即将完成,则当前线程释放cpuelse if (s == COMPLETING) // cannot time out yetThread.yield();// 第一次自旋,如果当前WitNode为null,new一个WaitNode结点else if (q == null)q = new WaitNode();// 第二次自旋 , 如果当前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// 挂起当前线程 , 该线程会休眠(什么时候该线程会继续执行呢?除非有其他线程调用unpark()或者中断该线程)LockSupport.park(this);}}5.finishCompletion()方法
//任务执行完成(正常结束和非正常结束都代表任务执行完成)会调用这个方法来唤醒所有因调用get()方法而陷入阻塞的线程 。private void finishCompletion() {// 如果条件成立,说明当前有陷入阻塞的线程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;// 执行到这里说明还有因调用get()而陷入阻塞的线程,自旋接着唤醒// 这里q.next设置为null帮助GC(垃圾回收)q.next = null; // unlink to help gcq = next;}break;}}//拓展方法done();// 将callable设置为null,方便GCcallable = null;}【3】注意事项
1)当 for 循环批量获取 Future 的结果时容易 block,get 方法调用时应使用 timeout限制
2)Future 的生命周期不能后退 。一旦完成了任务 , 它就永久停在了“已完成”的状态 , 不能从头再来

推荐阅读