Java 根据CPU核心数确定线程池并发线程数

2021/7/16 8:05:46

本文主要是介绍Java 根据CPU核心数确定线程池并发线程数,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、抛出问题

关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下:

第一派:《Java Concurrency in Practice》即《java并发编程实践》,如下图:

http://img4.sycdn.imooc.com/60f07c7100012d2007720637.jpg

如上图,在《Java Concurrency in Practice》一书中,给出了估算线程池大小的公式:

Nthreads=Ncpu*Ucpu*(1+w/c),其中

Ncpu=CPU核心数

Ucpu=cpu使用率,0~1

W/C=等待时间与计算时间的比率

第二派:《Programming Concurrency on the JVM Mastering》即《Java 虚拟机并发编程》

http://img2.sycdn.imooc.com/60f07c710001342906560769.jpg

线程数=Ncpu/(1-阻塞系数)

二.分析

对于派系一,假设cpu100%运转,即撇开CPU使用率这个因素,线程数=Ncpu*(1+w/c)。

现在假设将派系二的公式等于派系一公式,即Ncpu/(1-阻塞系数)=Ncpu*(1+w/c),===》阻塞系数=w/(w+c),即阻塞系数=阻塞时间/(阻塞时间+计算时间),这个结论在派系二后续中得到应征,如下图:

http://img1.sycdn.imooc.com/60f07c720001a01805620230.jpg

由此可见,派系一和派系二其实是一个公式……这样我就放心了……

三、实际应用

那么实际使用中并发线程数如何设置呢?分析如下(我们以派系一公式为例):

Nthreads=Ncpu*(1+w/c),w是阻塞时间,c是计算时间,Ncpu是cpu核数(可用处理器数目)

IO密集型:一般情况下,如果存在IO,那么肯定w/c>1(阻塞耗时一般都是计算耗时的很多倍),但是需要考虑系统内存有限(每开启一个线程都需要内存空间),这里需要上服务器测试具体多少个线程数适合(CPU占比、线程数、总耗时、内存消耗)。如果不想去测试,保守点取1即,Nthreads=Ncpu*(1+1)=2Ncpu。这样设置一般都OK。

计算密集型:假设没有等待w=0,则W/C=0. Nthreads=Ncpu。

至此结论就是:

IO密集型=2Ncpu(可以测试后自己控制大小,2Ncpu一般没问题)(常出现于线程中:数据库数据交互、文件上传下载、网络数据传输等等)

计算密集型=Ncpu(常出现于线程中:复杂算法)

java中:Ncpu=Runtime.getRuntime().availableProcessors()

end


作者:二十六画生的博客
链接:https://juejin.cn/post/6985042008297455629
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。




这篇关于Java 根据CPU核心数确定线程池并发线程数的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程