根据CPU核心数确定线程池并发线程数
关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下:
第一派:《Java Concurrency in Practice》即《java并发编程实践》,如下图:

解释:
Nthreads=Ncpu*Ucpu*(1+w/c),其中
Ncpu=CPU核心数(java可以使用Runtime.getRuntime().availableProcessors();获得)
Ucpu=cpu使用率,0~1
W/C=等待时间与计算时间的比率
第二派:《Programming Concurrency on the JVM Mastering》即《Java 虚拟机并发编程》

解释:
计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近1。
一般,我们让线程执行的任务是比较复杂的,不会是单一的计算密集型任务,或者单一的IO密集型任务,通常会夹杂着。那么就需要我们去计算阻塞系数了。阻塞系数的定义就是执行该任务阻塞的时间与(阻塞时间+计算时间)的比值,也就是w/(w+c)。
比较:
对于派系一,假设cpu100%运转,即撇开CPU使用率这个因素,线程数=Ncpu*(1+w/c)。
现在假设将派系二的公式等于派系一公式,即Ncpu/(1-阻塞系数)=Ncpu*(1+w/c),===》阻塞系数=w/(w+c),即阻塞系数=阻塞时间/(阻塞时间+计算时间),这个结论在派系二后续中得到应征,如下图:

由此可见,派系一和派系二公式计算结果其实是相通的
结论:
IO密集型:一般情况下,如果存在IO,那么肯定w/c>1(阻塞耗时一般都是计算耗时的很多倍),但是需要考虑系统内存有限(每开启一个线程都需要内存空间),这里需要上服务器测试具体多少个线程数适合(CPU占比、线程数、总耗时、内存消耗)。如果不想去测试,保守点取1即,Nthreads=Ncpu*(1+1)=2Ncpu。这样设置一般都OK。
计算密集型:假设没有等待w=0,则W/C=0. Nthreads=Ncpu。
总结:公式再好以实用为主,设置之后上机测试适时调整最大限度发挥效率。
摘自:
https://blog.csdn.net/u013276277/article/details/82630336
https://www.cnblogs.com/dennyzhangdd/p/6909771.html
https://blog.csdn.net/xichenguan/article/details/41309035
https://blog.csdn.net/partner4java/article/details/9417663

浙公网安备 33010602011771号