在设置线程池线程个数的时候,经常会想到这个问题,是不是设置的线程数越多越好?理解这个问题之前我们要先清楚的知道我们为什么使用多线程。
一、为什么会使用多线程
使用多线程的主要目的我们应该都能回答的出来就是提高程序的性能,这个提高性能其实是指降低延迟,指发送请求到接收到数据的时间,和提搞吞吐量:单位时间能可以处理更多的请求。
降低延迟和提高吞吐量对应的方法有两种:优化算法和机器的硬件性能发挥到极致。
- 优化算法降低时间和空间复杂度,使的程序执行时间更短。
- 硬件的性能发挥到极致,具体的指提高 I/O 和 cpu 的利用率,如何提高 I/O 和 cpu 的利用率的举例:如果单核系统中只有一个程序执行又有 IO 操作和 Cpu 计算的代码,当程序执行 IO 操作的时候,Cpu 其实是空闲的,反之 IO 是空闲的,如果这个时候用两个线程去跑这段代码,一个线程执行 IO 操作 ,一个线程执行 Cpu 计算 ,这时 IO 和 Cpu 的利用率是不是发挥了极致?
二、创建多少线程比较合适
经过上面的分析,我们知道创建多少线程能够将硬件的利用率达到最高才是最好的线程数。
我们从线程的应用场景来分析,由于 IO 操作比 Cpu 计算耗时要久的多的,如果我们一段程序有 IO 操作和 Cpu 计算,我们可以称之为 IO 密集型计算。程序中没有 IO 操作只有 Cpu 的话称之为 Cpu 密集型程序。
IO 密集型,是指系统大部分时间在跟 I/O 交互,而这个时间内线程不会占用 CPU 来处理,即在这个时间范围内,可以由其他线程来使用 CPU,因而可以多配置一些线程。如何将硬件利用率达到极致呢?我们将 R = IO 耗时 / Cpu 耗时 我们从上面的例子来看,如果 IO 耗时 / Cpu 耗时 = 10 (我们平常可以用工具 apm 来统计这个比例),创建线程 A 执行 IO 操作,我们希望 IO 操作的时候 Cpu 不能闲着,所以就应该创建 10 个线程去执行 Cpu 计算,当 IO 操作完毕后刚好 Cpu 也执行完毕,他们的利用率都是百分之百,在执行这段代码的时候。这个例子我们要创建 1 + 10 = 11 个线程执行起来效率更高,于是我们就得到了公式: 1 + I/O耗时 / Cpu耗时,如果是多核 Cpu 最佳线程数 = CPU 核数 * [ 1 +(I/O 耗时 / Cpu 耗时)]。
Cpu 密集型,就是指系统大部分时间是在做程序正常的计算任务,例如数字运算、赋值、分配内存、内存拷贝、循环、查找、排序等,这些处理都需要 CPU 来完成。这个就很简单了,Cpu 的核数 = 线程数就行,一般我们会设置 Cpu 核数 + 1,防止由于其他因素导致线程阻塞等。
三、结束语
看到这里想必大家在回答创建多个线程比较合理这个问题有了新的思路,希望能够帮助各位小伙伴!
网友评论