知识卡片

线程池要有边界

普通读书笔记卡 · 1503

内容

线程池的关键不是把任务丢进去,而是容量边界:核心/最大线程数、队列长度决定过载走向。Executors 快捷方法把边界隐藏了——newFixedThreadPool 用无界队列,堆积会把压力藏进内存直到 OOM;newCachedThreadPool 最大线程数无限制。应显式用 ThreadPoolExecutor 构造器设边界,见 [[拒绝策略决定过载去向]]。

参考来源

- 位置:《Java高并发核心编程.卷2,多线程、锁、JMM、JUC、高并发设计模式》第1章《多线程原理与实战》1.6.11节《Executors快捷创建线程池的潜在问题》(源文件:_epub-src/OEBPS/Text/chapter42.xhtml) - 结论依据:原文指出 `newFixedThreadPool`/`newSingleThreadExecutor` 的工作队列是容量为 `Integer.MAX_VALUE` 的无界队列,任务堆积会导致 OOM;`newCachedThreadPool` 的最大线程数同样是 `Integer.MAX_VALUE`,可能无限创建线程耗尽 CPU 资源;并明确建议用标准构造器替代快捷方法,因此可以推出“线程池必须有明确容量边界”的结论。 - 原始内容:使用Executors创建的“固定数量的线程池”……潜在问题仍然存在于其workQueue属性上,该属性的值为LinkedBlockingQueue(无界阻塞队列)。如果任务提交速度持续大于任务处理速度,就会造成队列中大量的任务等待……很有可能导致JVM出现OOM异常……大家应该杜绝使用这些便捷方法,而是直接使用线程池ThreadPoolExecutor的构造器。