线程池数量配置的最佳实践

最近项目中任务需要晚上跑任务执行,由于单线程速度感人,需要创建一个线程池去执行,所以如何配置一个合适的线程数量成了一个问题,快来看我们的实践 ↓↓↓

业务背景:

为了按天维度统计一个核心功能的操作元信息,由于数据按天去统计,所以只能存储原始数据到 mongo,等到次日凌晨跑批任务去处理这部分信息,数据量有将近到百万。
启动任务时会根据时间片对任务进行切片然后丢到线程池去等待处理。

线程数量配置

回到正题,根据线程执行任务类型不同,线程池数量配置方法也略有不同。

CPU密集型任务

定义:CPU密集型的意思就是该任务需要大量运算,而没有阻塞,CPU一直全速运行。

CPU密集型任务只有在真正的多核CPU上才可能得到加速(通过多线程)。

CPU密集型任务配置尽可能少的线程数。

CPU密集型线程数配置公式:(CPU核数+1)个线程的线程池。

IO密集型任务

定义:IO密集型,即该任务需要大量的IO,即大量的阻塞。

在单线程上运行IO密集型任务会导致浪费大量的CPU运算能力浪费在等待。

所以IO密集型任务中使用多线程可以大大的加速程序运行,即使在单核CPU上,这种加速主要利用了被浪费掉的阻塞时间。

第一种配置方式:

由于IO密集型任务线程并不是一直在执行任务,则应配置尽可能多的线程。

配置公式:CPU核数 * 2。

第二种配置方式:

IO密集型时,大部分线程都阻塞,故需要多配置线程数。

配置公式:CPU核数 / (1 – 阻塞系数)(0.8~0.9之间)

比如:8核 / (1 – 0.9) = 80个线程数

阻塞系数计算方式:假如单个线程执行需要总时间为 100ms,其中 IO 总耗时为 90ms,此时阻塞系数的计算方式为 IO耗时/线程执行总耗时 即 90/100 = 0.9