到底线程池应该设置多少合适?

来自:码匠笔记(微信号:majiangbiji),作者:码匠笔记



大家都写过多线程应用,也都用过线程池,那么线程池究竟设置多少个合适呢?


想必这个问题困恼着我们很多人,我们中的大部分都是拍着脑袋决定的。针对 CPU 密集型的程序比较简单我们就不讨论了,但是对于 IO 密集型的程序究竟设置多少合适呢?


我查阅了 《Java虚拟机并发编程》 里面提供了一个公式如下:「关注订阅号回复“并发编程”获取 PDF


线程数 = CPU 核心数 *( 1 - IO 阻塞系数)


「网上的文章基本都是出自这本书,但是还写的鱼龙混杂,没头没尾,建议通读下这本书的第二章」


公式中提到的阻塞系数决定于你的程序的 IO 延迟程度,当然这也是需要通过经验评估出来的,下面的图呢就是一个具体例子测试情况,可以看出来线程池的大小对响应时间的比例,并不是线程越多越快,针对每一个程序都会有一个合适的点。当然这个公式给我们提供的是一个解决思路,并不是实际的数量,毕竟我们的程序的性能也是参差不齐的。所以我们需要参考上面的公式,结合自己程序的“阻塞”时间合理的评估一个数量。


图片来源:Java 虚拟机并发编程


为了更加深入理解这问题,我又查阅了极客时间最新的课程《Java并发编程实战》,里面也有讲到了一个公式,并且还配了一个图,可以更清晰的解释这个问题,它提供的是一个公式是:


线程数 = CPU 核心数 * ( 1 +(I/O 耗时 / CPU 耗时))


公式里面提到的 CPU 耗时我个人理解是业务逻辑部分需要的运行 CPU 的时间,并不是时间片的切换时间,因为纳秒级别的通常可以忽略。但是通常情况我们做多线程程序是把 CPU 的计算时间 + IO 的耗时逻辑放在一起的,所以如果你的程序也是这样的,那么你就需要注意一下了。


它用了一个图生动形象的解释了一下多线程任务是怎么切换的。由下图我们可以看到多个线程的切换,是不是更清晰的理解了多线程的运行原理?当然道理一样,具体的线程数还是得我们自己根据业务的上下文评估。书和极客时间的课程都是让我们更好的理解多线程,更好的评估。


图片来源:极客时间


说了这么多,简单的总结下,对于 IO 密集型程序,线程数通常情况下是 IO 耗时越久需要分配的线程数越多,这样每一个线程就可以快速的切换处理耗时的逻辑,以达到并行处理的效果。当然这个也不是无限大,因为要考虑带宽、磁盘的瓶颈。


对了,极客时间这个课程里面还是有很多干货的,我买了确实受益良多。比如内存的可见性、锁、各种并发包下面的关键字都有一个深入的剖析,并且最新的并发包下面的工具类也会进行介绍,确实值得一读。

推荐↓↓↓
Java编程
上一篇:为了学好Java,我尝试了这 6 个方法 下一篇:把Maven的架构,用法,坑点介绍的清清楚楚