线程数设定是个高频出现的题目,这个题目对于优秀的面试官希望得到的答案是面试者的思考过程,考察其分析线程数设定的思考方向是否全面(主要包括对操作系统线程的理解和实际设置经验)。比较差的面试官才会认为固定的公式是正确的。
首先看一下影响线程数的因素可能有哪些?
线程数的设定需要根据应用程序的需求和运行环境来决定,没有一个固定的最佳值。以下是一些影响线程数设定的关键因素:
根据我们前面提到的这些影响因素来看,主要和CPU核心数、以及应用类型等有关。简单一点的话,可以根据应用类型来套用以下公式(但是,实际应用起来,也不要死守着公式不放,公式只是可以当作参考):
上面的N为CPU总核数
但是,上面的公式中,前提要求是知道你的应用是IO密集型还是CPU密集型,那么,到底怎么样算IO密集,怎么样又算CPU密集呢?一个应用就真的能明确的定位出来是CPU密集还是IO密集吗?
所以,还有另外一个公式:
$ 线程数=CPU核心数×目标CPU利用率×\frac{(1+等待时间/计算时间)}{1}
$
等待时间是指线程在执行过程中花费在等待外部操作完成的时间。这些外部操作通常包括I/O操作(如读写文件、数据库操作、网络请求等)和其他资源的同步等待(如等待锁的释放)。在等待时间内,线程通常不占用CPU资源,因为它在等待某个事件或资源可用。
计算时间是指线程实际进行计算处理的时间,即线程在CPU上执行操作的时间。计算时间通常指的是CPU密集型操作,如数学计算、数据处理等。
在这个公式中,"等待时间 / 计算时间"的比例是一个关键因素,它帮助决定合适的线程数量以平衡CPU利用和等待效率:
上面给出了公式,但是这个公式建议大家可以参考,而不是直接套用。
一方面我们讲过了,线程数设置时还需要考虑JVM、机器资源等,还需要考虑超线程等技术,另外有时候我们看到的CPU核数也不一定就是真实的。
很多时候,我们的应用部署在云服务器上面,有时候给我们分配的机器显示的是8核的,但是你要知道你实际上使用的只是虚拟机而已,并不是物理机,实际上大多数情况下不能发挥出8核的作用来。
可以在刚上线的时候,先根据公式大致的设置一个数值,然后再根据你自己的实际业务情况,以及不断的压测结果,再不断调整,最终达到一个相对合理的值。
在说明压测的时候,要说清楚可接受的响应耗时是多少,大于这个阈值即是错误,错误率多少可接受。这样给出的线程池参数才合理。