java多线程(4)之FutureTask

来源:互联网 发布:黄金白银分析软件 编辑:程序博客网 时间:2024/06/05 11:49

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;}publicinterface Runnable {    public abstract void run();}

FutureTask内部实现了异步执行,获取异步任务的结果,判断任务是否完成,是否取消等逻辑处理。


FutureTask成员变量说明

变量类型 变量名称 说明 private volatile int state 任务当前的状态 private static final int NEW=0 任务开始时的初始化状态 private static final int COMPLETING=1 任务已经完成,但结果还未给outcome 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 任务被中断 private Callable callable 要执行的任务 private Object outcome 任务执行的结果 private volatile Thread runner 任务执行所在的线程 volatile WaitNode waiters 获取任务结果的等待线程包装类

FutureTask执行过程中任务状态的转变

  • NEW -> COMPLETING -> NORMAL:正常执行结束
  • NEW -> COMPLETING -> EXCEPTIONAL:执行中出现异常
  • NEW -> CANCELLED:任务被取消
  • NEW -> INTERRUPTING -> INTERRUPTED:任务被中断


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

以上的构造方法中都实现了state状态的初始化,第二个构造方法调用下面的方法将runnable转换为callable,第二个形参result接收返回的结果。

public static <T> Callable<T> callable(Runnable task, T result) {        if (task == null)            throw new NullPointerException();        return new RunnableAdapter<T>(task, result);    }    private static final class RunnableAdapter<T> implements Callable<T> {        private final Runnable task;        private final T result;        RunnableAdapter(Runnable task, T result) {            this.task = task;            this.result = result;        }        public T call() {            task.run();            return result;        }    }

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;// 任务体置空    }

至此任务callable的执行已经分析完毕,接下来分析获取任务的结果.


 public V get() throws InterruptedException, ExecutionException {        int s = state;        if (s <= COMPLETING)            s = awaitDone(false, 0L);//调用awaitDone        return report(s);    }    /**     * @throws CancellationException {@inheritDoc}     */    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);    }    //等待任务的执行结果(timed: 是否有时间限制  nanos: 指定的时间)    private int awaitDone(boolean timed, long nanos)        throws InterruptedException {                long startTime = 0L;         WaitNode q = null;        boolean queued = false;        for (;;) {            int s = state;            if (s > COMPLETING) {//判断状态是否完成,若完成直接返回                if (q != null)                    q.thread = null;                return s;            }            else if (s == COMPLETING)//任务已经完成,但是set()方法还未执行结束,让出cpu执行权                   Thread.yield();            else if (Thread.interrupted()) {//如果线程被中断,删除队列中当前的等待线程,并且抛出InterruptedException异常                removeWaiter(q);                throw new InterruptedException();            }            else if (q == null) {//q==null,初始化一个当前线程的等待节点                if (timed && nanos <= 0L)                    return s;                q = new WaitNode();            }            else if (!queued)//如果当前节点没有加入等待线程列表,就加入                queued = U.compareAndSwapObject(this, WAITERS,                                                q.next = waiters, q);            else if (timed) {//如果有时间限制                final long parkNanos;                if (startTime == 0L) { // first time                    startTime = System.nanoTime();                    if (startTime == 0L)                        startTime = 1L;                    parkNanos = nanos;                } else {                    long elapsed = System.nanoTime() - startTime;                    if (elapsed >= nanos) {//如果超出指定时间范围就让线程直接返回                        removeWaiter(q);                        return state;                    }                    parkNanos = nanos - elapsed;                }                // nanoTime may be slow; recheck before parking                if (state < COMPLETING)//时间范围内让线程阻塞,等待倒计时并被唤醒                    LockSupport.parkNanos(this, parkNanos);            }            else                LockSupport.park(this);//如果没有时间限制就让线程阻塞,直到异步任务执行结束被唤醒.        }    }

ok,大功告成.

原创粉丝点击