Callable、Future、FutureTask 运行流程

【why】

  1. 在Executor 框架中标识一种异步任务,
  2. 此外也可以用来表示一些时间较长的计算,这些计算可以在使用计算结果之前启动。

【how】

  1. FutureTask 的定义:表示一种抽象的可获得结果的计算。Callable 就是这种计算的实现方式,相当于一种可生成结果的Runnable。
  2. 三种状态:等待运行、运行中、执行完成,其中执行完成又分为正常结束、由于取消而结束、由于异常而结束。
  3. get() 方法:取决于任务的状态,如果任务已经完成,可以直接获取结果,否则,阻塞等待。FutureTask将计算的结果从执行计算的线程传递到获取这个结果的线程,而FutureTask保证了这个传递的正常进行。

【what】

  1. UML 类图

    FutureTask UML类图

     

  2. 任务状态
     
    /** 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;

     

  3. 工作流程
    1. 创建FutureTask对象
      new FutureTask<>(Callable<V> callable) 
      或 
      new FutureTask<>(Runable runnable, V result)
    2. Thread 调用 run 方法
      public void run() {
          // 如果状态不为NEW 或者 CAS设置当前线程失败则返回,只有一个线程可以run
          if (state != NEW ||
              !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                           null, Thread.currentThread()))
              return;
          try {
              Callable<V> c = callable;
              // NEW状态,调用Callable 的 call 方法计算结果值
              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 {
              // 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;
              if (s >= INTERRUPTING)
                  handlePossibleCancellationInterrupt(s);
          }
      }

       

    3. set(V v):设置结果值
      protected void set(V v) {
          // CAS 更新 NEW -> COMPLETING
          if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
              // 设置结果值
              outcome = v;
              // 更新 COMPLETING -> NORMAL
              UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
              // 释放所有等待结果的线程
              finishCompletion();
          }
      }

       

    4. get():计算未完成时,阻塞所有调用的线程
      public V get() throws InterruptedException, ExecutionException {
          int s = state;
          // 如果状态是NEW 或者 COMPLETING(完成中),则阻塞当前线程
          if (s <= COMPLETING)
              s = awaitDone(false, 0L);
          return report(s);
      }

       

    5. 阻塞线程
      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);
                  throw new InterruptedException();
              }
      
              int s = state;
              // 如果已完成,则返回结束状态
              if (s > COMPLETING) {
                  if (q != null)
                      q.thread = null;
                  return s;
              }
              // 如果在COMPLETING,还未超时
              else if (s == COMPLETING) // cannot time out yet
                  // 线程释放CPU占用,返回到running ,可运行状态
                  Thread.yield();
              else if (q == null)
                  // NEW 状态,新建一个等待节点
                  q = new WaitNode();
              else if (!queued)
                  // NEW 状态的WaitNode节点,未入队,进行CAS入队
                  queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                       q.next = waiters, q);
              else if (timed) {
                  // 如果是超时等待,计算剩余时长
                  nanos = deadline - System.nanoTime();
                  // 如果已到等待时长
                  if (nanos <= 0L) {
                      // 线程出队
                      removeWaiter(q);
                      return state;
                  }
                  // 否则,设置超时时间
                  LockSupport.parkNanos(this, nanos);
              }
              else
                  // 非超时等待,直接挂起当前线程
                  LockSupport.park(this);
          }
      }

       

    6. 为完成的任务,返回结果 或抛出异常
      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);
      }
    7. 说明:Callable 任务可以取消
      public boolean cancel(boolean mayInterruptIfRunning) {
          // 如果任务不是NEW且设置成INTERRUPTING 或 CANCELLED,直接返回false
          if (!(state == NEW &&
                UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
                    mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
              return false;
          try {    // in case call to interrupt throws exception
              // 可以NEW 状态中断
              if (mayInterruptIfRunning) {
                  try {
                      Thread t = runner;
                      if (t != null)
                          t.interrupt();
                  } finally { // final state
                      // INTERRUPTING -> INTERRUPTED
                      UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                  }
              }
              // 否则,NEW -> CANCELLED
          } finally {
              finishCompletion();
          }
          return true;
      }

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值