配置核心线程数
Java线程池如何合理配置核心线程数?分下面两个步骤分析:
第一步:先看下机器的CPU核数,然后再设定具体参数
CPU核数=Runtime.getRuntime().availableProcessors()
System.out.println(Runtime.getRuntime().availableProcessors());
第二步:分析下线程池处理的程序是CPU密集型,还是IO密集型
CPU 密集型
:核心线程数 = CPU核数 + 1
IO 密集型
:核心线程数 = CPU核数 * 2
注意:IO密集型 (某大厂实战经验)核心线程数 = CPU核数 / (1 - 阻塞系数)
例如阻塞系数为0.8 ,CPU核数为 4 ,则核心线程数为 20
CPU密集型(CPU-bound)
CPU密集型也叫计算密集型,指的是系统的硬盘,内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU loading 100%,CPU要读/写 I/O (硬盘/内存),I/O在很短的时间就可以完成,而CPU还有很多运算要处理,CPU loading很高。
在多重程序系统中,大部分时间用来做计算,逻辑判断等CPU动作的程序称之为 CPU 密集型。例如一个计算圆周率至小数点一千位以下的程序,在执行过程中绝大部分时间用在三角函数和开根号的计算,便是属于CPU 密集型的程序。
CPU密集型的程序一般而且CPU 占用率相当高。这可能是因为任务本身不太需要访问 I/O 设备,也可能是因为程序是多线程实现因此屏蔽了等待 I/O 的时间。
IO密集型(I/O-bound)
IO密集型指的是系统的CPU性能相对硬盘,内存要好很多,此时,系统运作,大部分的状况是CPU在等IO(硬盘/内存)的读/写 操作,此时CPU loading并不高。
IO密集型的程序一般在达到性能极限时,CPU占用率仍然较低。这可能是因为任务本身需要大量 IO 操作,而pipeline 做得不是很好,没有充分利用处理器能力。
CPU密集型和IO密集型对比
一般把任务划分为 计算密集型和 IO 密集型。
计算密集型任务:特点是要进行大量的计算,消耗CPU资源。比如计算圆周率,对视频进行高清解码等,全靠CPU的运算能力。这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,所以,要最高效的利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。
计算密集型任务由于主要消耗CPU资源,因此,代码运行效率非常重要。例如脚本语言运行效率很低,完全不适合计算密集型任务。
IO密集型任务: 涉及到网络,磁盘IO的任务都是IO密集型任务。这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为 IO 的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。常见的大部分任务都是IO密集型任务,比如Web应用。
IO密集型任务执行期间,99% 的时间都花在IO上,花在CPU上的时间很少,因此,如果用运行速度极快的C语言替换用Python这样运行速度极低的脚本语言,完全无法提升运行效率。对于IO密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,C语言最差。
小结:
计算密集型程序适合C语言或Java语言多线程执行,IO密集型适合脚本语言开发的多线程。