线程池参数需依任务类型设定:cpu密集型推荐核心数=cpu核数+1、最大数≈核心数;i/o密集型核心数=cpu核数×2、最大数=cpu核数×5~10;混合型核心数≈cpu核数×1.5、最大数≈cpu核数×3;队列须有界,拒绝策略选callerrunspolicy或abortpolicy,并监控活跃线程、队列大小及拒绝任务数。

CPU 密集型任务(如数值计算、图像编码)
这类任务几乎不等待,线程一启动就占满 CPU,多开线程反而降低效率。
- 核心线程数 = CPU 核数 + 1(推荐),或直接用
Runtime.getRuntime().availableProcessors() - 最大线程数 = 核心线程数(或最多 +1~2,留一点弹性)
- 队列必须是有界队列,比如
ArrayBlockingQueue(50),防止任务堆积吃光内存
I/O 密集型任务(如 HTTP 调用、数据库查询、文件读写)
线程大量时间在等响应,CPU 利用率低,可以并行更多线程来“填满”等待空隙。
- 核心线程数 = CPU 核数 × 2(保障基础并发能力)
- 最大线程数 = CPU 核数 × 5 ~ 10(根据压测结果调,TPS 高、平均等待长就往高设)
- 队列容量建议 20~200,宁可多起线程,也不让任务长期排队
混合型或业务系统(如订单服务、API 网关)
纯 CPU 或纯 I/O 很少,多数是计算+DB+缓存+远程调用的组合。
- 核心线程数 ≈ CPU 核数 × 1.5
- 最大线程数 ≈ CPU 核数 × 3
- 队列容量按公式算:峰值 TPS × 平均处理时间(毫秒) ÷ 1000,例如 TPS=600、耗时=80ms → 队列≈48,取整为 50
必须同步做的几件事
只调两个数字远远不够,配套措施不到位,再合理的线程数也会翻车。
-
禁用无界队列:别用
LinkedBlockingQueue()默认构造(容量是 Integer.MAX_VALUE),显式指定容量,比如new LinkedBlockingQueue(200) -
拒绝策略要兜底:生产环境推荐
CallerRunsPolicy(调用方自己执行,自然限流)或AbortPolicy(快速失败暴露问题),别用DiscardPolicy静默丢任务 -
监控关键指标:持续观察
activeCount(活跃线程)、queueSize(排队数)、rejectedTasks(被拒数量),一旦发现长期排队或频繁拒绝,就得立刻调参
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











