【why】
- 在Executor 框架中标识一种异步任务,
- 此外也可以用来表示一些时间较长的计算,这些计算可以在使用计算结果之前启动。
【how】
- FutureTask 的定义:表示一种抽象的可获得结果的计算。Callable 就是这种计算的实现方式,相当于一种可生成结果的Runnable。
- 三种状态:等待运行、运行中、执行完成,其中执行完成又分为正常结束、由于取消而结束、由于异常而结束。
- get() 方法:取决于任务的状态,如果任务已经完成,可以直接获取结果,否则,阻塞等待。FutureTask将计算的结果从执行计算的线程传递到获取这个结果的线程,而FutureTask保证了这个传递的正常进行。
【what】
- UML 类图
- 任务状态
/** Possible state transitions: * NEW -> COMPLETING -> NORMAL 正常的状态转移 * NEW -> COMPLETING -> EXCEPTIONAL 异常 * NEW -> CANCELLED 取消 * NEW -> INTERRUPTING -> INTERRUPTED 中断 */ 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对象
new FutureTask<>(Callable<V> callable) 或 new FutureTask<>(Runable runnable, V result)
- Thread 调用 run 方法
public void run() { // 如果状态不为NEW 或者 CAS设置当前线程失败则返回,只有一个线程可以run if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) return; try { Callable<V> c = callable; // NEW状态,调用Callable 的 call 方法计算结果值 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 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 int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }
- set(V v):设置结果值
protected void set(V v) { // CAS 更新 NEW -> COMPLETING if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { // 设置结果值 outcome = v; // 更新 COMPLETING -> NORMAL UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state // 释放所有等待结果的线程 finishCompletion(); } }
- get():计算未完成时,阻塞所有调用的线程
public V get() throws InterruptedException, ExecutionException { int s = state; // 如果状态是NEW 或者 COMPLETING(完成中),则阻塞当前线程 if (s <= COMPLETING) s = awaitDone(false, 0L); return report(s); }
- 阻塞线程
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; } // 如果在COMPLETING,还未超时 else if (s == COMPLETING) // cannot time out yet // 线程释放CPU占用,返回到running ,可运行状态 Thread.yield(); else if (q == null) // NEW 状态,新建一个等待节点 q = new WaitNode(); else if (!queued) // NEW 状态的WaitNode节点,未入队,进行CAS入队 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 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 任务可以取消
public boolean cancel(boolean mayInterruptIfRunning) { // 如果任务不是NEW且设置成INTERRUPTING 或 CANCELLED,直接返回false if (!(state == NEW && UNSAFE.compareAndSwapInt(this, stateOffset, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false; try { // in case call to interrupt throws exception // 可以NEW 状态中断 if (mayInterruptIfRunning) { try { Thread t = runner; if (t != null) t.interrupt(); } finally { // final state // INTERRUPTING -> INTERRUPTED UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); } } // 否则,NEW -> CANCELLED } finally { finishCompletion(); } return true; }
- 创建FutureTask对象