每天凌晨00点00分, 第一时间与你相约
每日英文
No one can go to bear for you, no one can get to get you strong.
没有人能够去替你承受,也没有人能够拿得走你的坚强。
每日掏心话
有时候,虽然能想明白,但心里就是接受不了。大道理人人都懂,小情绪却难以自控。
来自:只会一点java | 责编:乐乐
程序员小乐(ID:study_tech)第 951 次推文 图源:百度
往日回顾:计算机网络基础知识总结
正文
关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下:
第一派:《Java Concurrency in Practice》即《java并发编程实践》,如下图:
如上图,在《Java Concurrency in Practice》一书中,给出了估算线程池大小的公式:
Nthreads=NcpuUcpu(1+w/c),其中
Ncpu=CPU核心数
Ucpu=cpu使用率,0~1
W/C=等待时间与计算时间的比率
关注公众号程序员小乐回复关键字“Java”获取Java面试题和答案。
第二派:《Programming Concurrency on the JVM Mastering》即《Java 虚拟机并发编程》
线程数=Ncpu/(1-阻塞系数)
对于派系一,假设cpu100%运转,即撇开CPU使用率这个因素,线程数=Ncpu*(1+w/c)。
现在假设将派系二的公式等于派系一公式,即Ncpu/(1-阻塞系数)=Ncpu*(1+w/c),===》阻塞系数=w/(w+c),即阻塞系数=阻塞时间/(阻塞时间+计算时间),这个结论在派系二后续中得到应征,如下图:
由此可见,派系一和派系二其实是一个公式……这样我就放心了……
那么实际使用中并发线程数如何设置呢?分析如下(我们以派系一公式为例):
<code>Nthreads=Ncpu*(1+w/c)</code>
IO密集型:一般情况下,如果存在IO,那么肯定w/c>1(阻塞耗时一般都是计算耗时的很多倍),但是需要考虑系统内存有限(每开启一个线程都需要内存空间),这里需要上服务器测试具体多少个线程数适合(CPU占比、线程数、总耗时、内存消耗)。如果不想去测试,保守点取1即,Nthreads=Ncpu*(1+1)=2Ncpu。这样设置一般都OK。扩展一下:JAVA多线程和并发基础面试问答
计算密集型:假设没有等待w=0,则W/C=0. Nthreads=Ncpu。
至此结论就是:
IO密集型=2Ncpu(可以测试后自己控制大小,2Ncpu一般没问题)(常出现于线程中:数据库数据交互、文件上传下载、网络数据传输等等)
<code>计算密集型=Ncpu(常出现于线程中:复杂算法)</code>
java中:<code>Ncpu=Runtime.getRuntime().availableProcessors()</code>
关注公众号程序员小乐回复关键字“offer”获取算法面试题和答案。
当然派系一种《Java Concurrency in Practice》还有一种说法,
即对于计算密集型的任务,在拥有N个处理器的系统上,当线程池的大小为N+1时,通常能实现最优的效率。(即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保CPU的时钟周期不会被浪费。)
即,计算密集型=Ncpu+1,但是这种做法导致的多一个cpu上下文切换是否值得,这里不考虑。读者可自己考量。
选择线程池并发线程数的因素很多:任务类型、内存等线程中使用到所有资源都需要考虑。
欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。欢迎加入程序员小乐技术交流群。
猜你还想看
阿里、腾讯、百度、华为、京东最新面试题汇集
教你设计一个超牛逼的本地缓存!
Netty是个啥?简单来说就这!
面试官:为什么 wait() 方法需要写在while里、而不是if? 我回答不上来