FutureTask源码分析

FutureTask的继承关系
在这里插入图片描述

FutureTask的WaitNode静态内部类,一个WaitNode代表一个等待线程(线程调用get()方法后被阻塞)。
FutureTask维护着waiters列表,是一个WaitNode的单向链表,当Runnable任务执行完后会调用finishCompletion方法,会唤醒所有被get()方法阻塞的线程。

FutureTask初始化方法

当使用Runnable初始化时,会将Runnable包装成一个返回Void的Callable.

public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

public FutureTask(Runnable runnable, V result){
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }

//任务状态
    /* 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的run方法,执行任务,设置任务状态, 设置任务结果(唤醒等待的线程),有异常时也需要唤醒所有等待线程。

public void run() {
        //如果任务状态不是NEW或者更新runner域失败(其他线程竞争),直接返回
        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 = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex); //会唤醒等待线程
                }
                if (ran)
                   //1.将state从NEW设置为Completing
                   //2.将state从Completing设置为Normal
                   //3.唤醒等待线程
                    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;
            //只有state是New时,调用cancel方法时,如果设置了mayInterrupteIfRunning,会把state设置成为interrupting,否则将state 设置为Cancelled
            //如果任务状态是interrupt,则
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s); 
        }
    }

protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();
        }
    }

//state为new是都可以设置
public boolean cancel(boolean mayInterruptIfRunning) {
	//如果cancel时,state不是new,则返回cancel失败
        if (state != NEW)
            return false;
       
       //由于线程切换 
        if (mayInterruptIfRunning) {
            if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))
                return false;
            Thread t = runner;
            if (t != null)
                t.interrupt();
            UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state
        }
        else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))
            return false;
        finishCompletion();
        return true;
    }

runAndReset方法

周期性定时任务会使用此方法,执行任务,执行完后重新设置任务状态到初始状态

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
                   //不会设置state,一直保持NEW
                    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;
    }

总结

  • FutureTask维护着一个WaitNode链表,每一个节点是一个被阻塞的线程。
  • FutureTask包装着Runnable任务,执行完后,会将state设置为completing, 再变成Normal,最后唤醒所有等待线程
  • 当任务为周期性定时任务时,运行runAndReset方法,state保持着NEW值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值