一、线程池基础概念
1. 核心定义
线程池:基于池化思想管理线程的工具,维护多个线程等待分配任务,避免线程创建 / 销毁的开销,控制线程数量防止资源耗尽。
2. 核心优势
- 降低资源消耗:复用线程,减少创建 / 销毁损耗
- 提高响应速度:任务到达无需等待线程创建
- 提升可管理性:统一分配、调优和监控线程资源
- 扩展功能丰富:支持定时 / 周期性任务(如 ScheduledThreadPoolExecutor)
二、线程池创建方式
1. 推荐方式:ThreadPoolExecutor 构造器
核心构造方法
public ThreadPoolExecutor(
int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 非核心线程空闲存活时间
TimeUnit unit, // 存活时间单位
BlockingQueue<Runnable> workQueue, // 任务队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler // 拒绝策略
)
核心参数详解
| 参数 | 作用 | 关键说明 |
|---|---|---|
| corePoolSize | 核心线程数 | 初始化时无线程,任务到来时创建,默认不会回收(allowCoreThreadTimeOut 可修改) |
| maximumPoolSize | 最大线程数 | 核心线程 + 非核心线程的上限,队列满时才会创建非核心线程 |
| keepAliveTime | 非核心线程空闲时间 | corePoolSize == maximumPoolSize 时无效 |
| workQueue | 任务缓冲队列 | 核心线程满时存放任务,分有界 / 无界 / 同步队列 |
| threadFactory | 线程创建工厂 | 默认 Executors.defaultThreadFactory (),可自定义线程名称、优先级等 |
| handler | 拒绝策略 | 队列和最大线程数均满时触发 |
2. 不推荐方式:Executors 静态方法
弊端(阿里巴巴 Java 开发手册强制要求避免)
- FixedThreadPool/SingleThreadExecutor:队列长度为 Integer.MAX_VALUE,易堆积任务导致 OOM
- CachedThreadPool/ScheduledThreadPool:最大线程数为 Integer.MAX_VALUE,易创建大量线程导致 OOM
Executors 线程池类型对比
| 类型 | 线程构成 | 核心特点 | 应用场景 |
|---|---|---|---|
| FixedThreadPool | 核心线程固定 | 核心线程不回收,队列无界 | 控制最大并发数 |
| ScheduledThreadPool | 核心 + 非核心线程 | 非核心线程闲置立即回收 | 定时 / 周期性任务 |
| CachedThreadPool | 仅非核心线程 | 60s 空闲回收,线程数无界 | 短耗时、数量多的任务 |
| SingleThreadExecutor | 1 个核心线程 | 任务顺序执行,无需同步 | 单线程串行任务(如数据库操作) |
三、核心组件详解
1. 任务队列(workQueue)类型
- ArrayBlockingQueue(有界队列):长度固定,队列满时创建非核心线程,最大线程满则触发拒绝策略
- LinkedBlockingQueue(无界队列):长度无限,易因任务堆积导致 OOM
- SynchronousQueue(同步队列):长度为 0,不缓存任务,直接移交线程执行
2. 拒绝策略(RejectedExecutionHandler)
| 策略类型 | 核心逻辑 | 适用场景 |
|---|---|---|
| AbortPolicy(默认) | 丢弃任务并抛出 RejectedExecutionException | 关键业务(需及时感知异常) |
| DiscardPolicy | 丢弃任务不抛异常 | 无关紧要的业务 |
| DiscardOldestPolicy | 丢弃队列最久任务,重试提交当前任务 | 允许丢弃老任务的场景 |
| CallerRunsPolicy | 由提交任务的主线程执行 | 需所有任务执行完毕的场景 |
四、线程池使用方法
1. 任务提交方式
| 方法 | 返回值 | 适用场景 |
|---|---|---|
| execute(Runnable command) | 无 | 无需返回结果的任务 |
| submit(Runnable task) | Future<?> | 需判断任务是否完成 |
| submit(Callable<T> task) | Future<T> | 需获取任务执行结果 |
2. 批量任务执行
invokeAll(Collection<? extends Callable<T>> tasks):等待所有任务完成,返回所有结果invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit):超时取消未完成任务invokeAny(Collection<? extends Callable<T>> tasks):返回第一个完成的任务结果invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit):超时取消未完成任务
3. 定时 / 周期性任务(ScheduledThreadPoolExecutor)
schedule(Runnable/Callable task, long delay, TimeUnit unit):延时一次执行scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit):固定周期执行(以上次任务开始时间计算)scheduleWithFixedDelay(Runnable task, long initialDelay, long delay, TimeUnit unit):固定间隔执行(以上次任务结束时间计算)
4. 线程池关闭
| 方法 | 核心逻辑 | 线程池状态 |
|---|---|---|
| shutdown() | 不接收新任务,执行完队列中任务 | SHUTDOWN |
| shutdownNow() | 不接收新任务,中断正在执行的任务,返回未执行任务 | STOP |
| isTerminated() | 所有任务执行完毕返回 true | TERMINATED |
关闭方法对比

五、线程池参数设计公式
1. 核心线程数(corePoolSize)
- 公式:
核心线程数 = (每秒任务数 × 单个任务执行时间)× 80%(二八原则) - 示例:每秒 100 个任务,单个任务 0.1 秒 → 100×0.1×0.8=8(实际取 10 优化)
2. 任务队列长度(workQueue)
- 公式:
队列长度 = 核心线程数 / 单个任务执行时间 × 2 - 示例:核心线程数 10,单个任务 0.1 秒 → 10/0.1×2=200
3. 最大线程数(maximumPoolSize)
- 公式:
最大线程数 = (最大每秒任务数 - 队列长度)× 单个任务执行时间 - 示例:最大每秒 1000 个任务,队列长度 200,单个任务 0.1 秒 →(1000-200)×0.1=80
4. 空闲时间(keepAliveTime)
- 无固定公式,根据系统压力和任务间隔调整(默认 60s 可参考)
六、线程池核心原理
1. 任务执行流程

2. 线程池状态流转
线程池通过 ctl(AtomicInteger)维护状态(高 3 位)和工作线程数(低 29 位),五种状态流转如下:

3. 关键源码逻辑
(1)execute () 方法核心流程
- 工作线程数 < corePoolSize → 创建核心线程执行任务
- 线程池 RUNNING 且队列未满 → 任务入队
- 队列满且工作线程数 < maximumPoolSize → 创建非核心线程执行任务
- 队列和最大线程数均满 → 执行拒绝策略
(2)线程回收机制
- 非核心线程:空闲时间超过 keepAliveTime 时,通过
poll(keepAliveTime)超时回收 - 核心线程:默认不回收,
allowCoreThreadTimeOut=true时可回收 - 回收触发:
getTask()方法返回 null → 线程退出循环 → 执行processWorkerExit()善后
(3)异常处理机制
- 任务执行抛异常 → 线程退出 →
processWorkerExit()会创建新线程补充核心线程数 - 核心线程数不会因异常全部消失