Java多线程:创建多少线程才合适?

1、线程执行

线程的执行是由CPU进行调度的,一个CPU在同一时刻只会执行一个线程

操作系统利用了时间片轮转的方式,CPU给每个任务都服务一定的时间,然后把当前任务的状态保存下来,再加载下一个任务的状态后,继续服务下一个任务。任务的保存及再加载的过程叫作上下文切换,上下文切换会导致额外的开销

2、为什么要使用多线程?

度量性能的指标最核心的就是延迟和吞吐量。延迟指的是发出请求到收到响应这个过程的时间;延迟越短,意味着程序执行得越快,性能也就越好。吞吐量指的是在单位时间内能处理请求的数量;吞吐量越大,意味着程序能处理的请求越多,性能也就越好

使用多线程的主要目的:降低延迟,提高吞吐量

3、多线程的应用场景

要想降低延迟,提高吞吐量基本上有两个方向,一个方向是优化算法,另一个方向是将硬件的性能发挥到极致

在并发编程领域,提升性能本质上就是提升硬件的利用率,也就是提升I/O的利用率和CPU的利用率,需要解决CPU和I/O设备综合利用率的问题

假设程序按照CPU计算和I/O操作交叉执行的方式运行,而且CPU计算和I/O操作的耗时是1:1

如下图所示,如果只有一个线程,执行CPU计算的时候,I/O设备空闲;执行I/O操作的时候,CPU空闲,所以CPU的利用率和I/O设备的利用率都是50%
《Java多线程:创建多少线程才合适?》
如果有两个线程,如下图所示,当线程A执行CPU计算的时候,线程B执行I/O操作;当线程A执行I/O操作的时候,线程B执行CPU计算,这样CPU的利用率和I/O设备的利用率就都达到了100%
《Java多线程:创建多少线程才合适?》
如果CPU和I/O设备的利用率都很低,那么可以尝试通过增加线程来提高吞吐量

4、创建多少线程合适?

对于CPU密集型的计算场景,理论上线程的数量=CPU核数就是最合适的。不过在工程上,线程的数量一般会设置为CPU核数+1,这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以顶上,从而保证CPU的利用率

对于I/O密集型的计算场景,最佳线程数=1+(I/O耗时/CPU耗时),针对多核CPU,我目前见过两种比较合理的公式:

最佳线程数=CPU核数×[1+(I/O耗时/CPU耗时)]

线程数=CPU核数×目标CPU利用率×(1+平均等待时间/平均工作时间)

    原文作者:邋遢的流浪剑客
    原文地址: https://blog.csdn.net/qq_40378034/article/details/100556161
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞