• FutureTask类


    Future类是想解析:

    /**
     * 可以取消的异步计算类,时Future 的基础实现,包括:
     * 启动和取消计算,查询计算是否完成以及检索计算结果,只有计算完成才能检索结果,否则将导致阻塞,一旦计算完成不能重启动和取消(除非runAndReset)
     * 可以用来包装Runnable和Future接口(因为实现了两个接口),可以用来提交给Executor
     * protected方法自定义子类时也很有用*/
    public class FutureTask<V> implements RunnableFuture<V> {
    
        /**
         * 任务的状态集合
         * 初始时为NEW,运行状态转换为终态只有通过设置:setException、cancel
         * 状态有可能是COMPLETIING(当结果正在被设置)或者INTERRUPTING(只有当中断运行满足:cancel(true))
         * 中间态--》终态通常使用廉价的:有序/延迟 写 因为结果是唯一且不可修改的
         * volatile确保线程可见性
         * 可能的状态转变:
         * 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;
    
        /** 基础的callable,运行后将被清空 */
        private Callable<V> callable;
        /** 用于返回或者throws的结果 */
        private Object outcome; // non-volatile 受 state reads/wirtes保护
        /** 运行runnable的线程, CASed during run() */
        private volatile Thread runner;
        /** Treiber stack of waiting threads 等待线程栈 */
        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);//异常结束
        }
    
        /**
         * 给定callable创建FutureTask对象
         * given {@code Callable}.*/
        public FutureTask(Callable<V> callable) {
            if (callable == null)
                throw new NullPointerException();
            this.callable = callable;
            this.state = NEW;       // 确保对callable可见
        }
    
        /**
         * 运行时执行给定runnable,执行完成后返回给定result.
         * 不想得到特定结果时:Future<?> f = new FutureTask<Void>(runnable, null)}*/
        public FutureTask(Runnable runnable, V result) {
            this.callable = Executors.callable(runnable, result);
            this.state = NEW;       // 确保callable的可见性
        }
      /**
       * 是否被取消
       */
    public boolean isCancelled() { return state >= CANCELLED;//取消、中断中、中断 } public boolean isDone() { return state != NEW;//状态不为新建即完成 }   /**
       *取消任务:是否中断
       *
       */
    public boolean cancel(boolean mayInterruptIfRunning) {
        //新建状态,且NEW --》CAS设置为CANCELLED或者INTERRUPTING(mayInterruptIfRunning=true)成功
    if (!(state == NEW && STATE.compareAndSet (this, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false;//状态非新建或者状态CAS失败直接返回 try { // 防止interrupt调用异常 if (mayInterruptIfRunning) { try { Thread t = runner; if (t != null) t.interrupt();//中断任务运行线程 } finally { // final state STATE.setRelease(this, INTERRUPTED);//设置任务状态INTERRUPTED } } } finally { finishCompletion();//完成计算 } return true;//返回true } /** * CancellationException取消异常,其他文档见Future*/ public V get() throws InterruptedException, ExecutionException { int s = state; if (s <= COMPLETING)//状态小于等于COMPLETIONG则等待计算完成 s = awaitDone(false, 0L);//等待计算结果状态 return report(s);//获取执行结果 } /** * CancellationException 取消异常,其他文档见Future*/ 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);//获取计算结果 } /** * 任务完成时(isDone()正常计算完成或通过取消)会调用此protected方法 * 默认空实现,子类可以重写实现callbaxk或记录 * Note:可以在方法的实现中查询状态以确定此任务是否取消 */ protected void done() { } /** * 设置计算结果为指定值(除非任务已经canceled或者被设置) * 计算完成后在run()方法内部调用此set(V)*/ protected void set(V v) { if (STATE.compareAndSet(this, NEW, COMPLETING)) {//CAS设置状态 NEW-》COMPLETING outcome = v; STATE.setRelease(this, NORMAL); // 终态:NORMAL finishCompletion();//完成计算 } } /** * 将导致get方法抛出ExecutedException执行异常给定的Throwable作为cause * 条件:任务未被canceled和set * 在run()方法内被调用*/ protected void setException(Throwable t) { if (STATE.compareAndSet(this, NEW, COMPLETING)) {//CAS设置状态 outcome = t; STATE.setRelease(this, EXCEPTIONAL); // 终态:EXCEPTIONAL finishCompletion(); } }
       /**
       * 任务执行命令
       *
       */
    public void run() { if (state != NEW ||//状态非NEW !RUNNER.compareAndSet(this, 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)//计算完成 set(result); } } finally { // 状态被设置后运行线程必须清空 // 防止并发调用run() runner = null; // 状态必须re-read在运行线程被设置后 // 防止中断泄漏 int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } } /** * 执行计算不设置结果并且重置任务为initial状态 * 如果任务执行异常或者cancelled将执行失败 * 这个方法为本质上不止执行一次的任务设计*/ protected boolean runAndReset() { if (state != NEW || !RUNNER.compareAndSet(this, null, Thread.currentThread())) return false; boolean ran = false; int s = state; try { Callable<V> c = callable; if (c != null && s == NEW) { try { c.call(); // 只计算,不设置状态 ran = true; } catch (Throwable ex) { setException(ex); } } } finally { runner = null; s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } return ran && s == NEW;//任务执行成功,且状态重置为NEW } /** * 确保将运行run()和 runAndReset()方法时的任何cancel(true)传递给任务 */ private void handlePossibleCancellationInterrupt(int s) { // interrupter(中断器)可能在获取interrupt任务机会之前停止,我们应给点机会 if (s == INTERRUPTING) while (state == INTERRUPTING) Thread.yield(); // 等待 待处理的 interrupt } /** * 简单的链表节点用于记录在Treiber栈中的等待线程 */ static final class WaitNode { volatile Thread thread;//当前节点中的线程 volatile WaitNode next;//在一个节点引用 WaitNode() { thread = Thread.currentThread(); }//此节点中的线程为当前线程 } /** * 移除并唤醒所有等待线程, 调用done()方法, * 外部不可调用 */ private void finishCompletion() { // 断言 state > COMPLETING; for (WaitNode q; (q = waiters) != null;) {//获取当前等待线程链表头节点 if (WAITERS.weakCompareAndSet(this, q, null)) {//CAS置换为null for (;;) {//遍历所有节点 Thread t = q.thread; if (t != null) { q.thread = null; LockSupport.unpark(t);//unpark等待节点中的线程 } WaitNode next = q.next; if (next == null) break; q.next = null; // 断开链接有助gc q = next; } break; } } done();//done()方法调用 callable = null; // 减少内存占用 } /** * 等待完成、超时或者中断*/ private int awaitDone(boolean timed, long nanos) throws InterruptedException { // 代码实现目标具体操作: // - 每次调用nanoTime执行暂停 // - 如果 nanos <= 0L, 理解返回没有分配或者nanoTime // - 如果 nanos == Long.MIN_VALUE, 不要回流 // - 如果 nanos == Long.MAX_VALUE, 并且 nanoTime 是非单调的 // 如果被虚假唤醒,有坑 park-spin 循环 long startTime = 0L; // 0代表尚未park 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)//结果正在被设置 // 通过isDone已经完成,结果不会是空或者InterruptedException Thread.yield(); else if (Thread.interrupted()) {//线程此前状态为中断 removeWaiter(q);//移除等待线程 throw new InterruptedException();//抛出InterruptedException } else if (q == null) {//结果计算中,且线程未被中断 if (timed && nanos <= 0L)//允许超时且已经超过等待时长 return s;//返回当前状态 q = new WaitNode();//当前线程计入等待节点 } else if (!queued)//未被队列 queued = WAITERS.weakCompareAndSet(this, q.next = waiters, q);//CAS设置当前等待节点未任务等待队列的队首 else if (timed) {//允许超时 final long parkNanos; if (startTime == 0L) { // 首次时间 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;//park时间 } // park前re-check状态 if (state < COMPLETING) LockSupport.parkNanos(this, parkNanos);//park } else LockSupport.park(this);//park } } /** * 尝试移除time-out 或 interruted 的等待节点,减少垃圾堆积 * 内部节点简单的解链,没有CAS 是无害的 * 避免影响已经移除的节点影响解链,如果存在竞争,该列表将被撤回 * 当节点过多时,会进行的很慢,但我们不希望列表过长导致更高的开销 */ private void removeWaiter(WaitNode node) { if (node != null) { node.thread = null; retry: for (;;) { // 重新开始在移除等待节点时遭遇竞争 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) // 检查竞争 continue retry; } else if (!WAITERS.compareAndSet(this, q, s)) continue retry; } break; } } } /** * 返回FutureTask的String视图*/ public String toString() { final String status; switch (state) { case NORMAL: status = "[Completed normally]"; break; case EXCEPTIONAL: status = "[Completed exceptionally: " + outcome + "]"; break; case CANCELLED: case INTERRUPTING: case INTERRUPTED: status = "[Cancelled]"; break; default: final Callable<?> callable = this.callable; status = (callable == null) ? "[Not completed]" : "[Not completed, task = " + callable + "]"; } return super.toString() + status; } // VarHandle mechanics private static final VarHandle STATE; private static final VarHandle RUNNER; private static final VarHandle WAITERS; static { try { MethodHandles.Lookup l = MethodHandles.lookup(); STATE = l.findVarHandle(FutureTask.class, "state", int.class); RUNNER = l.findVarHandle(FutureTask.class, "runner", Thread.class); WAITERS = l.findVarHandle(FutureTask.class, "waiters", WaitNode.class); } catch (ReflectiveOperationException e) { throw new ExceptionInInitializerError(e); } // 确保LockSupport已经加载,防止第一次使用时的异常情况
    Class<?> ensureLoaded = LockSupport.class; } }
  • 相关阅读:
    zookeeper、hbase集成kerberos
    hdfs、yarn集成kerberos
    kerberos(一) 详解
    Kerberos(一) 安装
    kerberos 配置错误记录
    javascript自定义滚动条插件,几行代码的事儿
    javascript,css延迟加载器
    DOM: 如何获取元素下的第一个子元素
    自定义标签的可用性
    (转)也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离)
  • 原文地址:https://www.cnblogs.com/gsanye/p/11167190.html
Copyright © 2020-2023  润新知