1. 为什么需要自定义线程池
在并发编程中,线程池是最基础也最重要的组件之一。Java标准库虽然提供了Executors工具类来创建线程池,但在实际生产环境中,我们往往需要更精细的控制。这就是为什么我们需要掌握自定义线程池的实现技巧。
重要提示:Executors.newFixedThreadPool()等工厂方法虽然方便,但在高并发场景下容易导致OOM,因为其默认使用无界队列。
我经历过的一个典型场景是电商秒杀系统。当使用默认线程池时,突发流量导致任务堆积,最终引发内存溢出。通过自定义线程池,我们能够:
- 精确控制队列容量
- 合理设置拒绝策略
- 根据业务特点调整线程生命周期
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 线程池核心参数详解
2.1 七大关键参数
一个完整的线程池需要配置以下参数:
| 参数名 | 说明 | 推荐设置 |
|---|---|---|
| corePoolSize | 核心线程数 | CPU密集型:N+1 IO密集型:2N |
| maximumPoolSize | 最大线程数 | corePoolSize的2-3倍 |
| keepAliveTime | 空闲线程存活时间 | 30-60秒 |
| unit | 时间单位 | TimeUnit.SECONDS |
| workQueue | 任务队列 | 建议有界队列 |
| threadFactory | 线程工厂 | 自定义命名 |
| handler | 拒绝策略 | 根据业务选择 |
2.2 队列选择策略
常见的队列类型及其适用场景:
-
ArrayBlockingQueue
- 特点:数组实现的有界队列
- 适用场景:固定大小的线程池
- 示例代码:
java复制new ArrayBlockingQueue<>(1000)
-
LinkedBlockingQueue
- 特点:链表实现,可选有界/无界
- 风险:默认无界可能导致OOM
- 改进方案:
java复制new LinkedBlockingQueue<>(5000)
-
SynchronousQueue
