线程池不主动感知资源不足,需通过有界队列防内存雪崩、合理设置线程数与存活策略、匹配业务容忍度的拒绝策略、以及运行时监控与动态干预来应对。

线程池本身不主动感知“运行中资源不足”(如内存溢出、CPU过载、文件句柄耗尽等),它只按预设规则调度任务。真正需要处理的是:当底层资源紧张导致任务执行失败或系统响应恶化时,如何让线程池机制配合做出合理应对。
用有界队列防止内存雪崩
无界队列(如 LinkedBlockingQueue 无参构造)是资源不足的常见诱因——任务持续堆积,最终引发 OutOfMemoryError。必须显式指定容量:
- 选用
ArrayBlockingQueue或带容量的LinkedBlockingQueue,例如new ArrayBlockingQueue(200) - 容量值需结合单任务平均内存占用与可用堆空间估算,避免过大(OOM风险)或过小(频繁拒绝)
- 配合 JVM 参数(如
-Xmx4g)预留足够堆空间给任务对象和线程栈
配置合理的线程数与存活策略
线程过多会加剧 CPU 竞争、上下文切换开销,甚至触发系统级资源限制(如 Linux 的 RLIMIT_NPROC):
- CPU 密集型任务:核心线程数建议设为
Runtime.getRuntime().availableProcessors()或加 1 - I/O 密集型任务:可适当提高(如 ×2~×4),但需监控实际线程阻塞率,避免盲目扩容
- 设置较短的
keepAliveTime(如 60 秒),及时回收空闲线程,释放栈内存和系统线程资源
拒绝策略要匹配业务容忍度
当队列满 + 线程数已达上限时,新任务必须被拒绝——这不是异常,而是主动限流:
立即学习“Java免费学习笔记(深入)”;
- AbortPolicy(默认):抛异常,适合强一致性场景,需上层捕获并降级
- CallerRunsPolicy:由提交线程自己执行,可自然减缓生产速度,避免雪崩
- DiscardOldestPolicy:丢弃队列中最老任务,适用于时效敏感型任务(如实时日志)
- 自定义策略:记录告警、写入磁盘暂存、触发熔断开关等
运行时监控与动态干预
仅靠静态配置不够,需结合运行态反馈及时调整:
- 定期采集
getActiveCount()、getQueue().size()、getCompletedTaskCount()等指标,接入 Prometheus 或日志告警 - 发现队列长期 >80% 满或活跃线程持续打满,说明资源配置偏紧,应扩容或优化任务逻辑
- 必要时调用
setCorePoolSize()或setMaximumPoolSize()动态调整(注意线程创建开销) - 对已知高资源消耗任务,单独隔离线程池,避免影响主流程


















