线程池设置多少个线程合适

分2派

  1. 来自<>书籍

线程池设置多少个线程合适_第1张图片

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

 

 

Ncpu=CPU核心数          Ucpu=cpu使用率,0~1         W/C=等待时间与计算时间的比率

  1. 来自《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)

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

如果不想去测试,保守点取1即,Nthreads=Ncpu*(1+1)=2Ncpu。这样设置一般都OK。

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

结论

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

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

即对于计算密集型的任务,在拥有N个处理器的系统上,当线程池的大小为N+1时,通常能实现最优的效率。(即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保CPU的时钟周期不会被浪费。)

 

即,计算密集型=Ncpu+1,但是这种做法导致的多一个cpu上下文切换是否值得,这里不考虑。

强烈建议,设置在理论值以及理论执行上下1-5个线程做压测,以压测数据为准

 

免费学习java就加这个qq:2444874641

你可能感兴趣的:(java)