1. 固定线程池实现与核心机制解析
固定线程池(FixedThreadPool)是Java并发编程中最基础的线程池实现之一,其核心特点是线程数量固定不变。与缓存线程池(CachedThreadPool)的动态伸缩不同,固定线程池在初始化时就确定了线程数量,这种设计特别适合处理持续稳定的任务流。
1.1 固定线程池的构造原理
通过ThreadPoolExecutor的构造方法,我们可以手动创建一个固定线程池:
java复制public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue
) {
// 构造方法实现
}
对于固定线程池,关键参数设置如下:
- corePoolSize和maximumPoolSize设置为相同值(如nThreads)
- keepAliveTime设置为0(因为线程数固定,不需要回收)
- 使用无界队列LinkedBlockingQueue
这种配置下,线程池会始终保持固定数量的工作线程,新任务到来时:
- 如果有空闲线程,立即执行
- 如果没有空闲线程,任务进入队列等待
- 由于队列无界,理论上可以接收无限多的任务
注意:实际开发中应谨慎使用无界队列,可能引发OOM问题。生产环境建议使用有界队列并配合合适的拒绝策略。
1.2 线程池工作流程详解
固定线程池的任务处理流程遵循标准线程池机制:
- 任务提交(execute()方法调用)
- 检查当前工作线程数:
- 小于corePoolSize:创建新线程立即执行
- 等于corePoolSize:任务入队
- 队列满时的处理(固定线程池使用无界队列,理论上不会满)
- 达到maximumPoolSize且队列满时触发拒绝策略
java复制// 典型execute方法执行流程
public void execute(Runnable command) {
if (command == null) throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true)) return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (!isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
2. 拒绝策略深度优化实践
当线程池无法处理新任务时(队列满且线程数达到maximumPoolSize),拒绝策略决定了如何处理这些"过载"任务。JDK默认提供了四种策略,但在实际业务中,我们往往需要自定义策略。
2.1 内置拒绝策略对比
| 策略名称 | 类名 | 行为特点 | 适用场景 |
|---|
