生产环境线程池必须显式用threadpoolexecutor构造,禁用executors工厂;按cpu/io密集型合理设核心/最大线程数、有界队列容量(100~2000)、自定义线程工厂与拒绝策略,并持续监控活跃线程、队列积压等指标。

生产环境用线程池,不能靠猜,也不能套模板。核心是让线程数、队列容量、拒绝策略三者匹配真实负载,同时避免资源失控。
必须手动创建,禁用Executors快捷工厂
Executors.newFixedThreadPool、newCachedThreadPool 等方法内部使用无界队列或无界线程池,极易引发 OOM 或线程爆炸。生产系统一律用 ThreadPoolExecutor 显式构造,所有参数可控可监控。
- ArrayBlockingQueue 或 LinkedBlockingQueue 必须设容量上限,例如 100~2000(根据任务平均处理时长和峰值吞吐反推)
- 禁止使用 SynchronousQueue 作为默认选择——它不缓冲任务,压力突增时直接触发拒绝,对稳定性不友好
- 线程工厂必须自定义,命名格式如 "order-processor-%d",便于日志追踪和线程 dump 分析
按任务类型设定核心与最大线程数
CPU密集型和IO密集型任务的线程需求完全不同,混用会拖垮性能。
-
CPU密集型(如图像压缩、数值计算):corePoolSize = CPU核数(
Runtime.getRuntime().availableProcessors()),maximumPoolSize ≤ corePoolSize × 1.5,keepAliveTime 可设为 30~60 秒 - I/O密集型(如HTTP调用、DB查询):corePoolSize = CPU核数 × 2~4,maximumPoolSize = CPU核数 × 4~8,队列容量建议设为最大线程数的 2~3 倍
- 混合型:优先压测;若无法压测,可用经验公式 Ncpu × Ucpu × (1 + W/C) 初步估算,其中 W/C 是平均等待时间与平均计算时间之比
拒绝策略不能用默认,要兜底可控
AbortPolicy(默认)在生产中等于“出错就崩”,CallerRunsPolicy 虽能降速但可能阻塞调用方主线程,都不适合核心链路。
- 关键业务推荐 自定义拒绝策略:记录被拒任务日志 + 写入本地磁盘或消息队列(如RocketMQ延迟重试Topic)+ 触发告警
- 非关键后台任务可用 DiscardPolicy(静默丢弃),但需配套监控指标:拒绝率 > 0.1% 即告警
- 慎用 DiscardOldestPolicy——丢老任务可能破坏业务语义(如订单生成顺序)
运行期必须监控,不能只配不管
线程池不是“一配了之”的静态组件,需持续观察其行为是否符合预期。
- 重点采集四项指标:活跃线程数(getActiveCount)、当前总线程数(getPoolSize)、队列积压量(getQueue().size())、已完成任务数(getCompletedTaskCount)
- 告警阈值参考:活跃线程数持续 ≥ maximumPoolSize × 0.9,或队列使用率 > 80%,或拒绝率连续 1 分钟 > 0.05%
- 建议集成 Micrometer + Prometheus,暴露为 /actuator/metrics/ 开头的指标端点
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











