概述
自jdk1.5之后 java提供了一个异步回调的类那就只FutureTask通过该类我们可以在多线程的环境下获得每个线程中函数执行之后的结果。
分析
首先我们从Thread函数开始分析
/** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that * <code>Runnable</code> object's <code>run</code> method is called; //实现Runnable接口类的run方法被启动 * otherwise, this method does nothing and returns. * <p> * Subclasses of <code>Thread</code> should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */
/* What will be run. */ private Runnable target; @Override public void run() { if (target != null) { target.run(); } }
接着我们来看下FutureTask
public class FutureTask<V> implements RunnableFuture<V> {}
public interface RunnableFuture<V> extends Runnable, Future<V> {}
通过以上两个声明可以得出结果FutureTask 实现类Runnable接口,那么在Threa执行run方法的时候执行的是FutureTask的run方法。
private Object outcome; // non-volatile, protected by state reads/writes 意思就是run的输出结果用outcome表示 /** The thread running the callable; CASed during run() */
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;
//构造函数如果传人一个callable的实现类则state=new=0
public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; // ensure visibility of callable }
public void run() { //判断Callable是否为真或者进行对线程的一些安全性判断 if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { //结果存入result result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } //如果结果没有发生异常则将result指向outcome 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); } }