如何估算 Java 线程池的大小与队列长度
估算算法
第一种估算算法
先来一个天真的估算算法:假设要求一个系统的 TPS(Transaction Per Second 或者 Task Per Second)至少为 20,然后假设每个 Transaction 由一个线程完成,继续假设平均每个线程处理一个 Transaction 的时间为 4s。那么问题可以转化为:如何设计线程池大小,使得可以在 1s 内处理完 20 个 Transaction?这里计算过程可以很简单,每个线程的处理能力为 0.25TPS,那么要达到 20TPS,显然需要 20/0.25=80 个线程。
很显然这个估算算法很天真,因为它没有考虑到 CPU 数目。一般服务器的 CPU 核数为 16 或者 32,如果有 80 个线程,那么肯定会带来太多不必要的线程上下文切换开销。
第二种估算算法
第二种估算算法比较简单,但不知是否可行(N 为 CPU 总核数):
- 如果是 CPU 密集型应用,则线程池大小设置为 N+1
- 如果是 IO 密集型应用,则线程池大小设置为 2N+1
如果一台服务器上只部署这一个应用并且只有一个线程池,那么这种估算或许合理,具体还需自行测试验证。