JUC下FutureTask类解析

一、UML类图

UML类图
Runnable是一个函数式接口,里面只有一个void run()方法,该接口位于java/lang/Runnable.java
Callable同样是一个函数式接口,相比Runable,它在JDK1.5中才出现,run方法更名为call方法,且拥有返回值。该接口位于java/util/concurrent/Callable.java
Future接口是与Callable接口成对出现的接口,可以通过get()接收Callable的返回值。
RunnableFuture则是继承了Runnable接口与Future接口的子接口。
FutureTask是RunnableFuture的实现类。

2.FutureTask作用

我们在日常使用中一般不会接触到FutureTask类,但是当我们试图通过Future类获取线程的返回结果,使用线程池的submit(new Runnable/new Callable)方法时,则会自动将Runnable实例对象与Callable的实例对象封装为FutureTask类型。

3.FutureTask代码及注释

package java.util.concurrent;
import java.util.concurrent.locks.LockSupport;

/*
    1.Runnable为Thread启动线程所需要的函数参数,该接口没有返回方法,而Callable相比于Runnable多了一个返回值。
    2.如果使用了submit方法,Runnble与Callable会与Future自动封装为FutureTask对象。
    3.Runable通过RunableAdater适配器模式转为Callable对象。
    4.可以使用线程池submit方法,返回Futue对象,通过get方法获取返回值。
 */
public class FutureTask<V> implements RunnableFuture<V> {
    
    
    //当前的task状态
    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对象,runnable使用适配器模式转为callable、
    private Callable<V> callable;
    //若正常,保存结果;若异常,callable抛出异常,outcome保存异常状态。
    private Object outcome; // non-volatile, protected by state reads/writes
    //任务被线程执行期间,保存当前执行的线程对象引用。
    private volatile Thread runner;
    //等待结果的线程栈。
    private volatile WaitNode waiters;
    //构造方法
    public FutureTask(Callable<V> callable) {
    
    
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
    //构造方法,使用适配器模式将Runnable转为了Callable结果可能为null也可能为传进来的值。
    public FutureTask(Runnable runnable, V result) {
    
    
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }

    @SuppressWarnings("unchecked")
    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);
    }

    public boolean isCancelled() {
    
    
        return state >= CANCELLED;
    }

    public boolean isDone() {
    
    
        return state != NEW;
    }

    public boolean cancel(boolean mayInterruptIfRunning) {
    
    
        //条件一:当前任务处于运行中,或处于线程池队列。
        //条件成立:修改状态成功。
        if (!(state == NEW &&
              UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
                  mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
            return false;

        try {
    
    
            if (mayInterruptIfRunning) {
    
    
                try {
    
    
                    //指向当前FutureTask的线程有可能是null,是null代表当前线程还没取到。
                    Thread t = runner;
                    if (t != null)
                        //正在执行,给该线程一个中断。
                        t.interrupt();
                } finally {
    
     // final state
                    //设置任务状态为中断完成。
                    UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                }
            }
        } finally {
    
    
            //唤醒所以get阻塞的线程。
            finishCompletion();
        }
        return true;
    }

    //多个线程等待当前执行完成后的结果。
    public V get() throws InterruptedException, ExecutionException {
    
    
        //查看当前状态
        int s = state;
        //如果是未执行或者正在执行,则调用get的外部线程会被阻塞。
        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);
    }

    protected void done() {
    
     }

    //线程执行成功,写入返回结果的函数
    protected void set(V v) {
    
    
        //执行成功将完成结果的值CAS写入,如果CAS失败则跳过set。
        //CAS失败的结果是外部线程cancel。
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
    
    
            //outcome写入返回值。
            outcome = v;
            //将状态修改为NORMAL。
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state

            finishCompletion();
        }
    }

    //逻辑同set。
    protected void setException(Throwable t) {
    
    
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
    
    
            outcome = t;
            UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
            finishCompletion();
        }
    }
    
    //任务执行入口
    public void run() {
    
    
        //条件一:state!=new 条件成立,说明task已经被执行了或者被取消了。
        //条件二:条件成立:cas失败,当前任务被其他线程抢占,
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        //当前task一定是new,而且当前线程也抢占task成功。
        try {
    
    
            //要执行的callable(适配后的runnable)
            Callable<V> c = callable;
            //条件一:防止空指针。
            //条件二:防止被cancel。
            if (c != null && state == NEW) {
    
    
                //保留一个结果引用,目前为null。
                V result;
                //表示callable.run执行成功(抛出异常)。
                boolean ran;
                try {
    
    
                    //调用call(),结果写入result。
                    result = c.call();
                    //执行成功。
                    ran = true;
                } catch (Throwable ex) {
    
    
                    //有异常结果为null。
                    result = null;
                    //执行失败。
                    ran = false;
                    //异常写入outcome。
                    setException(ex);
                }
                if (ran)
                    //如果成功了,将结果写入outcome。
                    set(result);
            }
        } finally {
    
    
            runner = null;
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }

    protected boolean runAndReset() {
    
    
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return false;
        boolean ran = false;
        int s = state;
        try {
    
    
            Callable<V> c = callable;
            if (c != null && s == NEW) {
    
    
                try {
    
    
                    c.call(); // don't set result
                    ran = true;
                } catch (Throwable ex) {
    
    
                    setException(ex);
                }
            }
        } 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
            s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
        return ran && s == NEW;
    }

    private void handlePossibleCancellationInterrupt(int s) {
    
    
        // It is possible for our interrupter to stall before getting a
        // chance to interrupt us.  Let's spin-wait patiently.
        if (s == INTERRUPTING)
            while (state == INTERRUPTING)
                Thread.yield(); // wait out pending interrupt

        // assert state == INTERRUPTED;

        // We want to clear any interrupt we may have received from
        // cancel(true).  However, it is permissible to use interrupts
        // as an independent mechanism for a task to communicate with
        // its caller, and there is no way to clear only the
        // cancellation interrupt.
        //
        // Thread.interrupted();
    }

    static final class WaitNode {
    
    
        volatile Thread thread;
        volatile WaitNode next;
        WaitNode() {
    
     thread = Thread.currentThread(); }
    }

    //set时应该先把get阻塞的线程唤醒。
    private void finishCompletion() {
    
    
        //q指向头结点
        for (WaitNode q; (q = waiters) != null;) {
    
    
            //使用CAS将waiters为null,防止外部线程cancel取消当前任务。
            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;
                    q.next = null; // unlink to help gc
                    q = next;
                }
                break;
            }
        }
        done();
        callable = null;        // to reduce footprint
    }

    //get方法需要栈,调用了该方法。
    private int awaitDone(boolean timed, long nanos)
        throws InterruptedException {
    
    
        //是否超时,0不带超时。
        final long deadline = timed ? System.nanoTime() + nanos : 0L;
        //引用当前线程封装成WaitNode对象。
        WaitNode q = null;
        //表示当前线程waitNode对象有没有压栈。
        boolean queued = false;
        //自旋
        for (;;) {
    
    
            //条件成立:说明当前线程被中断唤醒,调用该方法会重置中断状态。
            if (Thread.interrupted()) {
    
    
                //出栈
                removeWaiter(q);
                //get抛出中断异常
                throw new InterruptedException();
            }

            //条件成立:当前线程被其他线程使用unpark唤醒。
            //获取当前最新的状态。
            int s = state;
            //条件成立:说明当前任务已经完成。
            if (s > COMPLETING) {
    
    
                //条件成立:当前线程有node,需要将node的thread重置为null。
                if (q != null)
                    q.thread = null;
                //返回当前任务。
                return s;
            }
            //条件成立:当前线程正在执行,让当前线程yield。
            else if (s == COMPLETING) // cannot time out yet
                Thread.yield();
            //条件成立:第一次自旋,当前线程还未创建WaitNode对象,此时new一个该对象。
            else if (q == null)
                q = new WaitNode();
            //条件成立:第二次自旋,已经创建该对象,但是该对象未压栈。
            else if (!queued) {
    
    
                //当前线程node结点的next指向原对象的头结点。 waiters一直指向对象的头。
                q.next = waiters;
                //通过cas方式,设置waiters引用指向当前线程的node,成功为true。否则意味着有别的线程先行入栈。
                queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                        waiters, q);
            }
            //条件成立:第三次自旋,假设未使用超时设置,直接进入else。
            else if (timed) {
    
    
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L) {
    
    
                    removeWaiter(q);
                    return state;
                }
                LockSupport.parkNanos(this, nanos);
            }
            else
                //当前get操作的线程进行waiting状态。除非被其他线程唤醒或者当前线程中断。
                LockSupport.park(this);
        }
    }

    //出栈方法,由awaitdown调用。
    private void removeWaiter(WaitNode node) {
    
    
        if (node != null) {
    
    
            //将其引用线程重置为空。
            node.thread = null;
            retry://自旋
            for (;;) {
    
    
                //变量链表中每一个结点,pred上一个结点,q当前结点,s下一个结点
                for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
    
    
                    s = q.next;
                    //如果当前结点的线程引用不为空
                    if (q.thread != null)
                        pred = q;
                    //当前结点的线程是空,查看前一个结点是否为空。
                    else if (pred != null) {
    
    
                        pred.next = s;
                        if (pred.thread == null) // check for race
                            continue retry;
                    }
                    else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                          q, s))
                        continue retry;
                }
                break;
            }
        }
    }

    // Unsafe mechanics
    private static final sun.misc.Unsafe UNSAFE;
    private static final long stateOffset;
    private static final long runnerOffset;
    private static final long waitersOffset;
    static {
    
    
        try {
    
    
            UNSAFE = sun.misc.Unsafe.getUnsafe();
            Class<?> k = FutureTask.class;
            stateOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("state"));
            runnerOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("runner"));
            waitersOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("waiters"));
        } catch (Exception e) {
    
    
            throw new Error(e);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44159662/article/details/115058891
今日推荐