如何确定线程池大小

硬件资源、资源预算、任务类型都会影响线程池的理想大小。应用程序运行的环境会改变(机器扩容、缩容,资源使用率调整,其他可利用资源调整等),最好不要在代码中固定线程池的大小,而是动态的根据当前应用运行的环境进行调整。

过大或者过小的线程池都会导致系统吞吐率降低。线程池大小设置过大,大量的线程将竞争有限的 CPU 资源,导致性能下降;如果线程池设置过小,会有许多 CPU 空闲无法参与执行任务,从而导致吞吐率降低。

任务类型也影响线程池大小的设置。如果是计算密集型任务,将线程池大小设置为 CPU 个数 + 1 时,可以获得最优的利用率;多余的 1 个线程可以确保因为其他故障而阻塞的线程的时钟周期不被浪费。

获取当前环境的 CPU 个数:

int cpuCount = Runtime.getRuntime().availableProcessors();

《Java 并发编程实战》中给出的线程池大小计算方法:

N(线程数) = N(cpu个数) * U(cpu利用率) * (1 + 任务等待时间/任务执行)

除了 CPU 个数、任务类型之外,比如任务所依赖的数据库连接池大小、系统内存大小等因素也会制约线程池的大小,需要不断的尝试观察,才能得到一个相对理想的线程池大小。