必须显式构造 threadpoolexecutor 并配置全部 7 个参数,禁用 executors 工厂方法;使用有界队列、自定义线程工厂与 callerrunspolicy 拒绝策略,按业务隔离 bean,配合压测监控与优雅停机。

别用 Executors.newFixedThreadPool(),也别直接 new ThreadPoolExecutor 却不设参数——生产环境的线程池不是“能跑就行”,而是要扛住流量、防住 OOM、看得清状态、停得稳服务。
必须避开的 Executors 工厂陷阱
阿里《Java开发手册》明确禁止在生产代码中使用 newFixedThreadPool、newCachedThreadPool 等工厂方法。它们表面简洁,实则埋着三颗雷:
- 默认使用无界队列(
LinkedBlockingQueue),任务持续堆积 → 内存持续增长 → OOM - 核心线程数 = 最大线程数,无法弹性扩容,高峰来了只能排队或拒绝
- 拒绝策略是
AbortPolicy,直接抛异常,调用方若没兜底,业务就失败
7个参数一个都不能少:自定义 ThreadPoolExecutor
真正可控的线程池,必须显式构造 ThreadPoolExecutor,7个参数各司其职:
-
corePoolSize:常驻线程数。CPU 密集型建议设为
Runtime.getRuntime().availableProcessors() + 1;IO 密集型可设为×2~5(如 4 核机器配 8~12) - maximumPoolSize:最大并发线程上限。一般不超过 core 的 2~3 倍,避免上下文切换开销过大
-
keepAliveTime + unit:非核心线程空闲后存活时间,推荐
60L, TimeUnit.SECONDS -
workQueue:必须用有界队列,如
ArrayBlockingQueue(200),容量根据平均 QPS × 平均处理时长 × 安全系数估算 -
threadFactory:务必自定义,命名带业务前缀(如
"order-async-%d"),并设置setUncaughtExceptionHandler捕获未处理异常 -
handler:拒绝策略优先选
CallerRunsPolicy,让调用线程自己执行任务,自然限流降速
Spring Boot 中的规范落地方式
在 Spring 环境下,应声明为 @Bean 并统一管理,避免散落在各处:
- 每个业务场景单独配池(如订单异步、消息推送、定时补偿),不共用
- Bean 名称语义化(
@Bean("userRegisterAsyncExecutor")),便于日志和 APM 追踪 - 配合
@Async使用时,确保方法所在类由 Spring 管理,且调用走代理 - 服务关闭时触发优雅停机:
executor.shutdown()+awaitTermination(),必要时加超时兜底
上线前必做的三件事
配置完不等于可用,还需验证与观测:
- 压测时监控关键指标:
getActiveCount()(活跃线程)、getQueue().size()(排队数)、getRejectedExecutionCount()(拒绝次数) - 接入 Prometheus + Grafana,暴露线程池状态(如 Spring Boot Actuator 的
metrics端点) - 在拒绝策略里加告警(如记录到日志并触发企业微信/钉钉通知),拒绝 ≠ 静默丢弃
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











