线程池的核心成员变量¶
一、核心参数¶
public ThreadPoolExecutor(
int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 空闲存活时间
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 任务队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler // 拒绝策略
)
二、各参数作用¶
corePoolSize 核心线程数¶
常驻线程数。即使空闲也不回收(除非 allowCoreThreadTimeOut=true)。
maximumPoolSize 最大线程数¶
当队列满了,创建临时线程,最多到 maximum。
keepAliveTime 空闲存活时间¶
临时线程(超出 core 的部分)空闲超过这个时间就回收。
workQueue 任务队列¶
存等待执行的任务: - ArrayBlockingQueue:有界。 - LinkedBlockingQueue:无界(Executors 默认)。 - SynchronousQueue:不存,直接交给线程。
threadFactory 线程工厂¶
创建线程,自定义线程名、优先级、是否守护。
handler 拒绝策略¶
队列满、线程数到最大时,新任务怎么办: - AbortPolicy:抛异常(默认)。 - CallerRunsPolicy:调用者线程执行。 - DiscardPolicy:静默丢弃。 - DiscardOldestPolicy:丢最老的任务。
三、ctl 状态变量¶
一个 int 存两个信息: - 高 3 位:线程池状态。 - 低 29 位:线程数。
线程池状态¶
| 状态 | 含义 |
|---|---|
| RUNNING | 正常运行 |
| SHUTDOWN | 不接受新任务,处理完队列 |
| STOP | 不接受新任务,中断正在执行的 |
| TIDYING | 所有任务终止 |
| TERMINATED | terminated() 完成 |
四、为什么用一个 ctl¶
避免状态和线程数不一致。用 CAS 同时更新。
阿里规约
不要用 Executors 创建线程池(无界队列可能 OOM),手动 new ThreadPoolExecutor 明确参数。