Ch17-Java Executors 之 ThreadPoolExecutor

Ch17-Java Executors 之 ThreadPoolExecutor

April 10, 2020
Java | JUC
java

java.util.concurrent.ThreadPoolExecutor

1. 接口定义 #

public ThreadPoolExecutor(
    int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler);
状态 说明
corePoolSize 核心线程数
maximumPoolSize 最大线程数
keepAliveTime 非核心线程保持存活的时间,比如 TimeUnit.SECONDS
unit 非核心线程保持存活的时间单位
workQueue 任务存储队列,比如 SynchronousQueueLinkedBlockingQueueArrayBlockingQueue
threadFactory 当线程池需要新的线程时,会用 threadFactory 来生成新的线程
handler 拒绝策略,比如 AbortPolicyDiscardPolicyDiscardOldestPolicyCallerRunsPolicy

2. 基本原理 #

2.1 执行流程 #

executors

  1. 检测线程池运行状态,如果不是 RUNNING,则直接拒绝,线程池要保证在 RUNNING 的状态下执行任务。
  2. 如果 workerCount < corePoolSize,则创建并启动一个线程来执行新提交的任务。
  3. 如果 workerCount >= corePoolSize,且线程池内的阻塞队列未满,则将任务添加到该阻塞队列中。
  4. 如果 workerCount >= corePoolSize && workerCount < maximumPoolSize,且线程池内的阻塞队列已满,则创建并启动一个线程来执行新提交的任务。
  5. 如果 workerCount >= maximumPoolSize,并且线程池内的阻塞队列已满,则根据拒绝策略来处理该任务,默认的处理方式是直接抛异常。

2.2 线程数量变化 #

workerqueue

3. 线程池生命周期管理 #

线程池使用一个 AtomicInteger 类型的变量表示运行状态 (runState)线程数量 (workerCount)(高 3 位保存 runState,低 29 位保存 workerCount)。

注意 这里留意区分线程池的运行状态和线程的运行状态。

运行状态 说明
RUNNING 接收新任务和线程池队列中的任务
SHUTDOWN 不接受新任务,但是接收线程池队列中的任务
STOP 不接收新任务也不接收线程池队列中的任务,并且打断正在进行中的任务
TIDYING 所有任务终止,待处理任务数量为 0 的时候,线程转换为 TIDYING 状态,将会执行 terminated 钩子函数
TERMINATED terminated 函数执行完成后会变为此状态

state

4. 参考文献 #