线程数与 CPU 核心数关系:
第一种:
线程数=CPU 核心数CPU 使用率(1+W/C)
W/C:等待时间与计算时间的比率
第二种:
计算密集型服务:线程数=CPU 核心数
创建处理器可用核心数与线程数一致就可以,无需启动更多线程;这种情况如果创建更多的线程对程序性能而言反而是不利的,这种情况下当有多个处理就绪状态时,处理器核心需要在线程间频繁进行上下文切换,而这种切换对程序性能损耗较大。
IO 密集型服务:线程数》CPU 核心数
当执行一个任务 IO 操作时,其线程将被阻塞,于是处理器可以立即执行上下文切换以便于处理其他就绪线程,如果我们只有处理器可用核心数,那么多个线程的话,则即使有待执行的任务也无法执行处理,因为我们已经拿不出更多的线程供处理器调度了。
如果任务有 50% 的时间处于阻塞状态,则程序所需线程数为处理器可用核心数的两倍,如果任务呗阻塞的时间少于 50%,即这些任务是计算密集型的,则程序所需要的线程数将随之减少,但最少也不应该低于处理器的核心数。如果任务被阻塞的时间大于执行时间,即该任务是 IO 密集型的,就需要创建比处理器核心数大几倍数量的线程。
线程数=CPU 可用核心数/(1-阻塞系数),其中阻塞系数的取值为 0-1 之间;
计算密集型阻塞系数为 0;
IO 密集型的阻塞系数接近 1;
阻塞系数,可用采用一些性能分析工具或 java.lang.management API 来确定线程花在系统 IO 操作上的时间与 CPU 密集任务所耗时间的比值;
IO 密集型:一般情况下,如果 IO 那么肯定 W/C>1,(阻塞耗时一般都是计算耗时的很多倍),但需要考虑系统内存有限,每开启一个线程都需要内存空间,这里需要上服务器测试具体多少个线程数合适,CPU 占比,线程数,总耗时,内存消耗,如果无法进行测试验证,则可以取 1,线程数=CPU 核心数 x2
计算密集型:假设没有等待 W=0,则 W/C=0,线程数=CPU 核心数。