FutureTask是一个执行异步任务并可以取消及获得任务结果的实现类,类关系如下:
public class FutureTask<V> implements RunnableFuture<V>{...} public interface RunnableFuture<V> extends Runnable, Future<V> { void run(); } public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; } public interface Runnable { public abstract void run(); }FutureTask内部实现了异步执行,获取异步任务的结果,判断任务是否完成,是否取消等逻辑处理。
FutureTask成员变量说明
变量类型变量名称说明private volatile intstate任务当前的状态private static final intNEW=0任务开始时的初始化状态private static final intCOMPLETING=1任务已经完成,但结果还未给outcomeprivate static final intNORMAL=2任务执行完成private static final intEXCEPTIONAL=3任务执行出现异常private static final intCANCELLED=4任务执行被取消private static final intINTERRUPTING=5任务被中断中private static final intINTERRUPTED=6任务被中断private Callablecallable要执行的任务private Objectoutcome任务执行的结果private volatile Threadrunner任务执行所在的线程volatile WaitNodewaiters获取任务结果的等待线程包装类FutureTask的构造函数
public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; } public FutureTask(Runnable runnable, V result) { this.callable = Executors.callable(runnable, result); this.state = NEW; }FutureTask中的实现方法
//这是实现的接口Future<V>中的方法: //返回任务是否取消 public boolean isCancelled() { return state >= CANCELLED; } //返回任务是否完成 public boolean isDone() { return state != NEW; } //取消或者中断任务(true为中断,false为取消) public boolean cancel(boolean mayInterruptIfRunning) { if (!(state == NEW && U.compareAndSwapInt(this, STATE, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false; try { // in case call to interrupt throws exception if (mayInterruptIfRunning) { try { Thread t = runner; if (t != null) t.interrupt(); } finally { // final state U.putOrderedInt(this, STATE, INTERRUPTED); } } } finally { finishCompletion(); } return true; } //获取任务的执行结果,如果任务还未结束一直处于阻塞状态 public V get() throws InterruptedException, ExecutionException { int s = state; if (s <= COMPLETING) s = awaitDone(false, 0L);//会在这里阻塞,直到任务执行结束或者出现异常 return report(s);//返回执行的结果 } // 在指定的时间内获取结果,超时会抛出TimeOutException结束,未超时会一直等下去 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); } 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); }FutureTask中子线程执行的run方法
public void run() { if (state != NEW || (如果不是初始化状态就必要执行,直接返回) !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread())) (CAS方式修改RUNNER线程为当前任务所在执行的线程) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call();//执行callable中的方法 ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex);//出现异常调用setException } if (ran) set(result);//执行成功设置state状态及结果outcome的值 } } finally { int s = state; if (s >= INTERRUPTING)//如果任务被中断了就执行handlePossibleCancellationInterrupt handlePossibleCancellationInterrupt(s); } } protected void setException(Throwable t) { //(1)首先修改state值为COMPLETING if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = t;//(2)为outcome赋值为Throwable对象 //(3)最后修改state值为EXCEPTIONAL U.putOrderedInt(this, STATE, EXCEPTIONAL); // final state finishCompletion(); } } protected void set(V v) { //(1)首先修改state值为COMPLETING if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = v;//(2)为outcome赋值为Throwable对象 (3)最后修改state值为EXCEPTIONAL U.putOrderedInt(this, STATE, NORMAL); finishCompletion(); } } //无论任务正常完成还是出现异常都会调用该方法,将等待列表线程唤醒,并清除任务体 private void finishCompletion() { // assert state > COMPLETING; for (WaitNode q; (q = waiters) != null;) { if (U.compareAndSwapObject(this, WAITERS, 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;// 任务体置空 }ok,大功告成.