Java多线程深入学习-FutureTask与Callable实现解析

Callable接口定义

/**
 * 定义一个函数式接口Callable
 */
@FunctionalInterface
public interface Callable<V> {
    /**
     * 定义一个call方法
     */
    V call() throws Exception;
}

Future接口定义

/**
 * 调用不带参数的get方法的调用被阻塞,直到计算完成。
 * 		如果在计算完成之前,调用带参get()方法超时时,会抛出TimeoutException异常。
 * 		若运行该计算的线程被中断,两种get()方法都会抛出InterruptedException。如果计算已经完成,那么get方法立即返回。
 * 若计算还在进行,isDone方法返回false;如果完成了,则返回true。
 * 调用cancel()时,若计算还没有开始,它被取消且不再开始。若计算处于运行之中,那么如果mayInterrupt参数为true,它就被中断。
 * 相比future.get(),其实更推荐使用get (long timeout, TimeUnit unit) 方法,因为设置了超时时间可以防止程序无限制的等待future的返回结果。
 */
public interface Future<V> {

    /**取消任务。参数:是否立即中断任务执行,或者等等任务结束 */
    boolean cancel(boolean mayInterruptIfRunning);
    /** 任务是否已经取消,若已取消,返回true */
    boolean isCancelled();
    /** 任务是否已经完成。包括任务正常完成、抛出异常或被取消,都返回true */
    boolean isDone();
    /** 
     * 等待任务执行结束,获得V类型的结果。
     * 	InterruptedException: 线程被中断异常, 
     * 	ExecutionException: 任务执行异常,
     * 	如果任务被取消,还会抛出CancellationException 
     */
    V get() throws InterruptedException, ExecutionException;
    /**
     * 参数timeout指定超时时间,uint指定时间的单位,在枚举类TimeUnit中有相关的定义。
     * 如果计算超时,将抛出TimeoutException
     */
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

RunnableFuture接口定义

/** 定义接口 继承 Runnable和 Future*/
public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}

FutureTask源码解析

/**
 * 定义FutureTask类实现RunnableFuture接口
 */
public class FutureTask<V> implements RunnableFuture<V> {
	/** 定义线程状态 以及一些常量 */
    private volatile int state;	// 确保callable的可见性,因为state是volatile修饰的,
    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是计算结果的代码块 也就是执行的代码块 */
    private Callable<V> callable;
    /** callable的计算结果保存在这,这个字段不是volatile的,由state的读写来保护 */
    private Object outcome;
    /** 运行的线程 */
    private volatile Thread runner;
    /** 等待结果的队列 */
    private volatile WaitNode waiters;

    @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 FutureTask(Callable<V> callable) {
        if (callable == null)	//校验callable
            throw new NullPointerException();
        this.callable = callable;	//赋值
        this.state = NEW;	//设置执行状态为NEW
    }
    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);	//利用runnable生成一个Callable对象
        this.state = NEW; 	//设置执行状态为NEW
    }

    /** 直接对比状态 */
    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; //操作失败  可能呗其他线程操作了 直接返回false 这里只是修改状态  还未停止线程
        try {    // in case call to interrupt throws exception
            if (mayInterruptIfRunning) {	//是否强制停止
                try {
                    Thread t = runner;	//获取当前执行的线程
                    if (t != null)
                        t.interrupt();	//将线程中断
                } finally { // final state
                    UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);	//修改状态
                }
            }
        } finally {
            finishCompletion();	//完成处理  唤醒所有等待线程
        }
        return true;
    }

    /** 获取执行结果 */
    public V get() throws InterruptedException, ExecutionException {
        int s = state;	//获取线程当前状态
        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) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { 修改状态为COMPLETING  
            outcome = v;	//执行结果设置
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); //修改状态为NORMAL  
            finishCompletion();	//执行完成处理
        }
    }

    /**
     * 设置异常信息
     */
    protected void setException(Throwable t) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { //修改状态为COMPLETING  只有一个能成功
            outcome = t;	//执行结果设置成异常
            UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); //修改状态为COMPLETING  只有一个能成功
            finishCompletion();	//执行完成处理
        }
    }

    /** run方法  线程启动后执行的方法 */
    public void run() {
    	//确保task不会被重复执行
        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();	//执行callable的call方法获取结果
                    ran = true;	//执行成功 结果为true
                } catch (Throwable ex) {	//捕获到异常,执行失败
                    result = null;	//返回结果为空
                    ran = false;	//执行结果为false
                    setException(ex);	//设置异常信息
                }
                if (ran)	//是否执行成功
                    set(result);	//设置结果值
            }
        } finally {
            runner = null;	//置空当前线程
            
            //线程运行时已经接收到了中断请求,测试state为INTERRUPTING状态,需要确保state
            //变成INTERRUPTED状态。INTERRUPTING->thread.interrupt()->INTERRUPTED
            int s = state;
            if (s >= INTERRUPTING)	//执行状态
                handlePossibleCancellationInterrupt(s);	//内部自旋使用Thread.yeild()
        }
    }

    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) {
        if (s == INTERRUPTING)
            while (state == INTERRUPTING)	//自选等待中断完成
                Thread.yield(); 
    }

    static final class WaitNode {
        volatile Thread thread;
        volatile WaitNode next;
        WaitNode() { thread = Thread.currentThread(); }
    }
    
    /**
     * 完成当前任务	唤醒所有等待结果线程
     */
    private void finishCompletion() {
        for (WaitNode q; (q = waiters) != null;) {	//是否有等待结果的队列
            if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {	//队列设置为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; 
                    q = next;	//遍历
                }
                break;	//跳出循环
            }
        }

        done();	//子类扩展用

        callable = null; //清空callable信息
    }

    /**
     * 中断线程,等待任务执行
     */
    private int awaitDone(boolean timed, long nanos)
        throws InterruptedException {
        final long deadline = timed ? System.nanoTime() + nanos : 0L;
        WaitNode q = null;
        boolean queued = false;
        for (;;) {
        	 //等待线程被中断了,移除等待节点
            if (Thread.interrupted()) { //获取线程中断状态并重置该状态
                removeWaiter(q);	//移除等待队列中节点q
                throw new InterruptedException();	//抛出异常
            }

            int s = state;	//获取任务执行状态
            if (s > COMPLETING) {	//已执行完成
                if (q != null)	//q不为null
                    q.thread = null;	//清空节点数据
                return s;	//返回当前执行状态
            }
            else if (s == COMPLETING) // 还未执行完成
                Thread.yield();	//当前线程让出cpu
            else if (q == null)	//节点为空
                q = new WaitNode();	//新建一个几点
            else if (!queued)
                queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                     q.next = waiters, q);	//将节点放入等待队列
            else if (timed) {	//是否有时间限制
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L) {	//等待时间到了 
                    removeWaiter(q);	//移除节点q
                    return state;	//返回线程当前状态
                }
                LockSupport.parkNanos(this, nanos); //将线程挂起等待被唤醒,或者超时
            }
            else
                LockSupport.park(this);	//将线程挂起等待被唤醒
        }
    }

    /**
     * 删除等待队列中的某个节点
     */
    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;	
                    //thread不为null,说明是有效节点,更新前驱节点继续后移
                    if (q.thread != null)
                        pred = q;
                    //thread为null,需要将p节点移除
                    else if (pred != null) {
                    	//移除p节点
                        pred.next = s;
                        //判断pred节点的thread是否为null,如果为null,说明pred节点可能被
                        //另一个线程移除了。那么pred显然是已经脱离了链表,上一步的操作
                        //是无效的,需要从链表头部重新遍历。
                        if (pred.thread == null) // check for race
                            continue retry;
                    }
                    //要移除的节点是头结点,CAS将后继结点设置成头。如果失败,说明链表结构 发生了变化,需要从链表头部重新遍历
                    else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                          q, s))
                        continue retry;
                }
                break; //遍历到了尾部,break
            }
        }
    }

    /**
     * 引入Unsafe并静态获取内存地址
     * stateOffset  state的内存地址
     * runnerOffset  runner的内存地址
     * waitersOffset  waiters的内存地址
     */
    private static final Unsafe UNSAFE;
    private static final long stateOffset;
    private static final long runnerOffset;
    private static final long waitersOffset;
    static {
        try {
            UNSAFE = 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/luo_mu_hpu/article/details/106624097
今日推荐