今天我们来聊一个经典却容易被滥用的工具:线程池(ThreadPoolExecutor) 。
很多人写代码就是一把梭:
ExecutorService executor = Executors.newFixedThreadPool(10);
这样用当然简单,但——
面试官:你知道它底层怎么实现的吗?你知道什么时候该用自定义线程池吗?
1️⃣ 线程池的核心概念
线程池主要靠 ThreadPoolExecutor 这个类实现。它有几个核心参数:
✅ corePoolSize(核心线程数)
✅ maximumPoolSize(最大线程数)
✅ keepAliveTime(空闲线程存活时间)
✅ workQueue(任务队列)
✅ threadFactory(线程工厂)
✅ handler(拒绝策略)
简单来说:
- 核心线程 + 队列处理任务
- 队列满了才用非核心线程
- 都满了才触发拒绝策略
2️⃣ Executors 系列的坑
⚠ newFixedThreadPool() → 核心线程固定,队列是无界的,任务太多可能撑爆内存
⚠ newCachedThreadPool() → 没有限制,瞬间大量并发可能把 CPU 打死
⚠ newSingleThreadExecutor() → 单线程,适合串行化任务,不适合高并发
建议生产代码用:
new ThreadPoolExecutor(...) 自定义线程池
3️⃣ 自定义线程池怎么配?
实战配置示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, // 核心线程数
20, // 最大线程数
60, TimeUnit.SECONDS,// 空闲线程存活时间
new ArrayBlockingQueue<>(100), // 队列容量
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);
常用拒绝策略:
✅ AbortPolicy → 抛异常(默认)
✅ CallerRunsPolicy → 谁提交谁自己跑
✅ DiscardPolicy → 直接丢弃
✅ DiscardOldestPolicy → 丢掉最老的任务
4️⃣ 小幽默:线程池的“过劳死”
我见过有人在循环里 newFixedThreadPool,每次都 new 一个线程池,结果服务器直接炸了……
线程池:兄弟,咱也是有生命的,别无限造我啊!
5️⃣ 总结
✅ Executors 工厂类方便,但不适合生产
✅ 要搞清楚线程池参数配置和队列类型
✅ 自定义 ThreadPoolExecutor 是高级 Java 工程师的基本功
✅ 多线程不是万能的,搞错了只会让系统更慢、更脆弱