这个问题,在实际开发和面试中,出现的频率还是非常高的。
使用线程池的最大目的,其实是为了最大限度的去利用cpu资源,提高系统的性能。在评估线程数量之前,我们需要先分析业务场景,一般会有以下几种情况:
- 任务执行时间短,并发高
- 任务执行时间短,并发不高
- 任务执行时间长,并发高
- 任务执行时间长,并发不高
第1种 和 第2种,任务执行时间短,这种场景比较简单,线程数可以设置为 CPU 核数+1(这个额外的1主要是为了确保偶尔出现故障时,CPU时间片不被浪费 ), 减少线程上下文的切换(这是重点)。
第3种 和 第4种,任务执行时间长,这个要分情况看的,要区分是IO密集型任务,还是CPU密集型任务。
1)CPU密集型的,通常是CPU需要大量的计算,耗时主要在CPU上,这种情况不是线程越多,性能越好,因为开启线程主要耗的资源就是CPU。线程数设置和第1种一样即可,CPU核数+1,减少线程上下文切换。
2)IO密集型的,因为IO操作是不占用CPU的,所以为了不让CPU闲着,可以加大线程数。具体可参考CPU耗时和IO耗时,比如cpu耗时是10ms,IO耗时1000ms,那么线程数可设置为(1000 / 10)* N,N是CPU核数。
如果是执行时间长,同时又是高并发的业务,关键不在于线程的数量,更多应该去考虑怎么从架构上去优化,比如想办法减少任务执行时间(使用缓存、MQ异步处理)等,其次可以考虑增加服务器资源。
对于线程数量的设置,没有一个完美的公式,要结合实际业务去分析和压测,才能得到一个正确的数字。