一针见血系列[2]: 线程池里面到底该设置多少个线程呢?论Java多线程和CPU核数的关系

栏目:一针见血 作者:admin 日期:2018-10-29 评论:0 点击: 3,869 次

在Java中,通过下面的代码,我们可以很容易地获取到系统可用的处理器核心数目:

基本原则是:应用程序的最小线程数应该等于可用的处理器核数。具体场景又分为以下两种情况:

(1)如果所有的任务都是计算密集型的,则创建处理器可用核心数那么多个线程就可以了。在这种情况下,创建更多的线程对程序性能而言反而是不利的。因为当有多个任务处于就绪状态时,处理器核心需要在线程间频繁进行上下文切换,而这种切换对程序性能损耗较大。
(2)如果任务都是IO密集型的,那么我们就需要开更多的线程来提高性能。当一个任务执行IO操作时,其线程将被阻塞,于是处理器可以立即进行上下文切换以便处理其他就绪线程。如果我们只有处理器可用核心数那么多个线程的话,即使有待执行的任务也无法处理,因为我们已经拿不出更多的线程供处理器调度了。
总之,如果任务有50%的时间处于阻塞状态,则程序所需线程数为处理器可用核心数的两倍。如果任务被阻塞的时间少于50%,即这些任务是计算密集型的,则程序所需线程数将随之减少,但最少也不应低于处理器的核心数。如果任务被阻塞的时间大于执行时间,即该任务是IO密集型的,我们就需要创建比处理器核心数大几倍数量的线程。计算出程序所需线程的总数的公式如下:

线程数=CPU可用核心数/(1-阻塞系数),其中阻塞系数的取值在0和1之间。

计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近1。一个完全阻塞的任务是注定要挂掉的,所以我们无须担心阻塞系数会达到1。

一针见血系列[2]: 线程池里面到底该设置多少个线程呢?论Java多线程和CPU核数的关系:等您坐沙发呢!

发表评论