线程池核心参数与执行原理
线程池是 Java 并发编程的基石,理解其运作机制对性能调优至关重要。核心参数主要有七个:
- corePoolSize:核心线程数,线程池维持的最小活跃线程数。
- maximumPoolSize:最大线程数量,允许创建的最大线程数(核心 + 救急)。
- keepAliveTime:非核心线程的存活时间,空闲超时后会被回收。
- unit:存活时间的单位。
- workQueue:工作队列,用于缓存待执行任务。当核心线程满时,新任务进入队列。
- threadFactory:线程工厂,用于定制线程名称、是否为守护线程等属性。
- handler:拒绝策略,当队列和线程数都达到上限时的处理方案。
执行流程简述:
- 任务提交后,若当前线程数小于 corePoolSize,则创建新核心线程执行。
- 若核心线程已满,任务进入 workQueue 等待。
- 若队列已满且线程数小于 maximumPoolSize,则创建非核心线程执行。
- 若队列和线程数均达上限,触发 handler 拒绝策略。
常见阻塞队列对比
常用的阻塞队列包括 ArrayBlockingQueue 和 LinkedBlockingQueue,两者底层结构不同导致性能差异明显:
| 特性 | ArrayBlockingQueue | LinkedBlockingQueue |
|---|---|---|
| 底层结构 | 数组 | 链表 |
| 容量限制 | 强制有界 | 默认无界,可指定容量 |
| 节点创建 | 初始化时创建 | 插入时动态创建 |
| 锁机制 | 两把锁(头尾分离) | 一把锁 |
LinkedBlockingQueue 采用锁分离设计,生产者和消费者互不干扰,适合吞吐量要求较高的场景。
核心线程数如何确定?
没有固定公式,需结合业务指标调整。一般参考以下经验值:
- CPU 密集型任务:计算密集,上下文切换开销大。建议
CPU 核数 + 1。 - IO 密集型任务:读写多,CPU 占用低。建议
CPU 核数 * 2 + 1。 - 高并发短任务:减少线程切换,可适当增加线程数。
实际生产中,应设定预期 CPU 利用率、负载及 GC 频率,通过压测不断微调。
常用线程池类型
JUC 包中的 Executors 提供了四种典型实现:
- FixedThreadPool:固定线程数,无救急线程,使用 LinkedBlockingQueue。适合任务量已知、耗时较长的场景。
- SingleThreadExecutor:单线程池,按序执行。相比普通单线程,线程复用减少了创建销毁开销。
- CachedThreadPool:可缓存线程池,核心为 0,最大为 Integer.MAX_VALUE。适合任务密集但执行时间短的场景,空闲线程 1 分钟后回收。


