如何合理地设置 Java 线程池的线程数?
如何合理地设置 Java 线程池的线程数?
回答重点
线程池的线程数设置需要看具体执行的任务是什么类型的。
任务类型可以分:CPU 密集型任务和 I/O 密集型任务。
CPU 密集型任务
CPU 密集型任务,就好比单纯的数学计算任务,它不会涉及 I/O 操作,也就是说它可以充分利用 CPU 资源(如果涉及 I/O,在进行 I/O 的时候 CPU 是空闲的),不会因为 I/O 操作被阻塞,因此不需要很多线程,线程多了上下文开销反而会变多。
根据经验法则,CPU 密集型任务线程数 = CPU 核心数 + 1。
I/O 密集型任务
I/O 密集型任务,有很多 I/O 操作,例如文件的读取、数据库的读取等等,任务在读取这些数据的时候,是无法利用 CPU 的,对应的线程会被阻塞等待 I/O 读取完成,因此如果任务比较多,就需要有更多的线程来执行任务,来提高等待 I/O 时候的 CPU 利用率。
根据经验法则,I/O 密集型任务线程数 = CPU 核心数 * 2 或更多一些。
(这句话一定要和面试官说)以上公式仅是一个纯理论值,仅供参考!在生产上,需要考虑机器的硬件配置,设置预期的 CPU 利用率、CPU负载等因素,再通过实际的测试不断调整得到合理的线程池配置参数。
扩展
业界还有更多线程池参数设置公式,图来自美团技术:
Java 21 虚拟线程
Comments