CPU密集型任务
也叫计算密集型任务,这种类型大部分状况下,CPU使用时间远高于I/O耗时,计算要处理、许多逻辑判断,几乎没有I/O操作的任务就属于CPU密集型。 如果是CPU密集型任务,频繁切换上下线程是不明智的,此时应该设置一个较小的线程数,比如CPU的数目加1。
CPU密集型任务应配置尽可能小的线程,如配置CPU个数+1的线程数
IO密集型任务
IO密集型则是系统运行时,大部分时间都在进行I/O操作,CPU占用率不高 比如:任务对其他系统资源有依赖,如某个任务依赖数据库的连接返回的结果,这时候等待的时间越长,则CPU空闲的时间越长,那么线程数量应设置得越大,才能更好的利用CPU, 不让CPU闲下来, 但也不宜过多,需要注意线程切换的开销
IO密集型任务应配置尽可能多的线程,因为IO操作不占用CPU,不要让CPU闲下来,应加大线程数量,如配置两倍CPU个数+1。
混合型任务
对于混合型的任务,如果可以拆分,拆分成IO密集型和CPU密集型分别处理,前提是两者运行的时间是差不多的,如果处理时间相差很大,则没必要拆分了。
配置线程池大小的原则-阻抗公式
我们发现线程池设置线程数与CPU计算时间和I/O操作时间的比例相关,一个配置线程池大小的原则——阻抗匹配原则,其经验公式为:
1. N = CPU数量
2. P = CPU繁忙时间 / 总运行时间 // 0<P<=1
3. T = 所需设置线程数
4. T = N / P
T个线程,每个线程占用P的时间,正好可以占满N个CPU,也就是N = T * P。
如果P = 1.0,N = 16,说明这是一个完全的密集计算,此时T = 16,也就是有几个CPU设置几个线程,这样能把CPU都利用起来。更多的线程也没用,因为CPU资源已经耗光。
如果P = 0.5,N = 16,说明每个线程只有一半的时间在使用CPU,此时T = 32,也就是32个中有一半(16个)繁忙的线程,另一半(16个)线程空闲, 才能充分把CPU利用起来。
如果P < 0.2,这个公式就不适用了,因为线程不能无限开,会消耗大量资源。T可以取一个固定值,比如 8*N。
综上,CPU繁忙时间占比越高,设置线程数越少,CPU繁忙时间占比越低,设置线程数越多(当然也要有限度)。