10年Java后端总结:这5个线程池坑,90%程序员都踩过
工作第 10 年,我 review 过上百个 Java 项目代码后发现一个扎心事实:
80% 的线上性能事故,都和线程池用错有关。
- CPU 飙升 100%
- 服务器 OOM
- 接口突然卡死
- 请求全部超时
最后排查:全是线程池配置不当!
今天把我这些年踩过的 5 个“血泪大坑”一次讲透。
新手尤其要看,第 3 个坑几乎人人中招。
❌ 坑一:直接用 Executors 创建线程池(最致命)
很多人都这样写:
Executors.newFixedThreadPool(10);Executors.newCachedThreadPool();看起来很优雅?
但实际上:
问题来了
源码里:
new LinkedBlockingQueue<>(Integer.MAX_VALUE)队列是无限的!!!
这意味着:
- 请求堆积
- 内存不断上涨
- 最终 OOM 崩溃
线上真实事故:
10w 请求堆积,直接把 JVM 打爆
✅ 正确姿势
永远手动创建:
new ThreadPoolExecutor( 10, 20, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1000));一定要限制队列容量!
❌ 坑二:corePoolSize = maxPoolSize
很多人图省事:
core = max = 50觉得这样更稳定?
错。
问题:
线程池失去弹性:
- 低峰期:浪费资源
- 高峰期:无法扩容
- 请求直接堆积
✅ 建议配置
通用经验值:
CPU密集型:CPU核数 + 1IO密集型:CPU核数 * 2~4示例:
core = 8max = 32让线程池能“伸缩”
❌ 坑三:队列太大(隐形慢性自杀)
很多人说:
“队列大一点更安全吧?”
于是:
new LinkedBlockingQueue<>(100000)结果:
后果:
- 请求排队 30 秒才执行
- 用户疯狂超时
- QPS 下降
- 服务雪崩
延迟比失败更可怕!
大队列 = 慢性死亡
✅ 建议
小队列 + 快速失败:
ArrayBlockingQueue<>(500)让系统:
- 快失败
- 快降级
- 快恢复
而不是一直排队等死。
❌ 坑四:没设置拒绝策略
默认策略:
AbortPolicy效果:
直接抛异常!
生产上就变成:
RejectedExecutionException接口全红。
✅ 推荐策略
方案一:CallerRunsPolicy(最稳)
new ThreadPoolExecutor.CallerRunsPolicy()让调用方线程执行,自动限流
方案二:自定义降级
(r, executor) -> { log.warn("线程池满了,走降级逻辑");}❌ 坑五:线程池用完不关闭
很多人忽略:
executor.shutdown();结果:
- 线程泄露
- JVM 无法退出
- 容器无法重启
线上排查能把人逼疯。
✅ 标准写法
try { executor.execute(task);} finally { executor.shutdown();}或者:
@PreDestroypublic void destroy() { executor.shutdown();}终极推荐配置模板(直接可用)
这是我线上项目通用模板:
public static ExecutorService buildExecutor() { return new ThreadPoolExecutor( 8, 32, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(500), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy() );}特点:
✅ 有界队列
✅ 可扩容
✅ 自动限流
✅ 防OOM
✅ 防雪崩
生产级安全。
最后总结(记住这 5 句话)
线程池避坑口诀:
✅ 不用 Executors
✅ 队列要小
✅ 线程可伸缩
✅ 配拒绝策略
✅ 记得 shutdown
只要做到这些:

99% 线上事故都能避免
如果你也是:
- Java 后端
- 做高并发
- 写中间件
- 搞微服务
关注我,后面继续分享:
真实线上事故复盘
JVM 调优实战
Spring 性能优化
高并发架构设计
让你少踩 10 年坑
文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有