corePoolSize是线程池中长期保持活跃的最小线程数,任务提交时优先由其处理,空闲时默认不销毁(除非启用allowCoreThreadTimeOut);它是线程池的“常驻底线”,而非最大容量。

corePoolSize 是什么
corePoolSize 指线程池中长期保持活跃的最小线程数。任务一来,优先交给这些线程处理;即使它们空闲着,也不会被回收(除非显式开启 allowCoreThreadTimeOut)。它不是“最大可用数”,而是“常驻底线”——相当于线程池的日常值班队伍。
CPU 密集型任务怎么设
这类任务持续占用 CPU,比如图像渲染、加密解密、复杂数学运算。线程太多反而引发频繁上下文切换,拖慢整体速度。
- 推荐值:等于或略大于 CPU 逻辑核心数,常见取 N 或 N + 1(N =
Runtime.getRuntime().availableProcessors()) - N+1 的意义在于:当某个线程因缺页、缓存未命中等短暂阻塞时,多出的 1 个线程能立即补上,不让 CPU 空转
- 不建议超过 N+2,尤其在高并发计算场景下,容易看到 CPU 利用率没涨、但响应延迟明显上升
IO 密集型任务怎么设
这类任务大量时间花在等待上——发 HTTP 请求、查数据库、读写磁盘。线程发起 IO 后就挂起,CPU 实际空闲,此时可让其他线程顶上。
- 不能只看 CPU 核心数,得估算线程“忙”和“等”的比例:公式为 corePoolSize ≈ N × (1 + W/C),其中 W 是平均等待时间,C 是平均计算时间
- 若无法精确测量,可用经验起点:2N~4N;Web 服务常见设为 20~100,具体取决于后端延迟(如 DB 响应慢,W/C 达 20,8 核机器可设 core=160)
- 注意内存开销:每个线程默认栈空间约 1MB,corePoolSize=200 就占 200MB 堆栈内存,需结合 JVM 堆外内存预留评估
混合型或不确定任务怎么办
现实中很多任务既有计算又有 IO(如一次请求里先解析 JSON,再调三次 API,最后聚合结果)。硬套单一公式容易失衡。
- 优先拆分:为纯计算类操作(如风控规则引擎)单独建小线程池(core=N),为远程调用类(如 Feign Client)配大线程池(core=3N~5N)
- 保守起步:先按 IO 密集型设(如 2N),上线后通过监控观察线程利用率(JVM Thread Count)、队列积压(workQueue.size())、拒绝率(RejectedExecutionException 次数)
- 动态微调:利用 setCorePoolSize() 在运行时调整,配合 Prometheus + Grafana 看板,发现持续积压就加,发现 CPU 持续 95%+ 且 GC 频繁就减

















