分2派
- 来自<<java并发编程实践>>书籍
Nthreads=Ncpu*Ucpu*(1+w/c),其中
Ncpu=CPU核心数 Ucpu=cpu使用率,0~1 W/C=等待时间与计算时间的比率
- 来自《Java 虚拟机并发编程》的书籍
线程数=Ncpu/(1-阻塞系数)其中为Ncpu为cpu核数
分析
对于派1,假设cpu100%运转,即撇开CPU使用率这个因素,线程数=Ncpu*(1+w/c)。
现在假设将派2的公式等于派系一公式,即Ncpu/(1-阻塞系数)=Ncpu*(1+w/c),推导出阻塞系数=w/(w+c),即阻塞系数=阻塞时间/(阻塞时间+计算时间)
可得出是一个公式
实战
Nthreads=Ncpu*(1+w/c)
- IO密集型:一般情况下,如果存在IO,那么肯定w/c>1(阻塞耗时一般都是计算耗时的很多倍),但是需要考虑系统内存有限(每开启一个线程都需要内存空间),这里需要上服务器测试具体多少个线程数适合(CPU占比、线程数、总耗时、内存消耗)。
如果不想去测试,保守点取1即,Nthreads=Ncpu*(1+1)=2Ncpu。这样设置一般都OK。
- 计算密集型:假设没有等待w=0,则W/C=0èNthreads=Ncpu
结论
- IO密集型=2Ncpu(可以测试后自己控制大小,2Ncpu一般没问题)(常出现于线程中:数据库数据交互、文件上传下载、网络数据传输等等)
- 计算密集型=Ncpu(常出现于线程中:复杂算法)
PS java中:Ncpu=Runtime.getRuntime().availableProcessors()
即对于计算密集型的任务,在拥有N个处理器的系统上,当线程池的大小为N+1时,通常能实现最优的效率。(即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保CPU的时钟周期不会被浪费。)
即,计算密集型=Ncpu+1,但是这种做法导致的多一个cpu上下文切换是否值得,这里不考虑。
强烈建议,设置在理论值以及理论执行上下1-5个线程做压测,以压测数据为准
免费学习java就加这个qq:2444874641