Java的FutureTask实现原理

Java的FutureTask实现原理

  1. Executor.submit(Callable call)
    submit步骤:

    • 将callable包装成一个FutureTask,这个类既是一个Future,又是一个Runnable,实现了RunnableFuture接口(适配器模式)
    • 线程池提交任务
      提交任务:将任务包装成一个worker,这个worker既持有任务,又持有线程(线程池中实际持有的是worker)。worker添加到线程池后,启动线程。执行逻辑如下:
      1. 执行worker持有的任务
      2. 任务执行完了以后设置FutureTask的outCome
      3. 唤醒在FutureTask上面等待的线程WaitNode结构(java.util.concurrent.FutureTask#finishCompletion)
      4. 从线程池中的阻塞队列中获取新的任务(在这里控制线程的存活时间),如果获取到新的元素,执行步骤1
      5. 从线程池中移除worker,任务结束
    • 返回futureTask
  2. Future.get()

    1. 如果任务已经计算出来结果,直接返回结果
    2. 否则构建将当前线程包装成一个WaitNode(链表),CAS把生成的waitNode插入到FutureTask的header,然后挂起当前线程。(java.util.concurrent.FutureTask#awaitDone)

线程池的执行流程

  1. 如果线程池中thread的size小于coreSize,新建线程执行任务
  2. 如果线程池中的thread数量大于coresize,将任务添加到任务队列中(尽可能高效的复用线程)
  3. 如果任务不能添加到任务队列并且thread的size小于maxSize,新建线程执行任务
  4. 执行拒绝策略

你可能感兴趣的:(Java的FutureTask实现原理)