面试官心理
面试官问这个问题,大家有没有想过底层逻辑是什么?
揣摩字面意思我们明白首先多创建线程是好的,为什么这么说呢?因为大家想呢现在我们的线上机器配置规格至少2核起步吧,很多S1级应用都标配4核8G的配置,利用多核CPU能力,假如能帮我们同时处理我们的任务,原来串型处理要200ms,那我2个线程同时处理那岂不时间节约一半,对不对。
好了很明显,这个问题其实考察的是一个多线程场景下的问题,利用多线程来充分利用CPU空闲资源,来提高我们应用的性能。
如果我们执行uptime操作系统命令
比如如下信息:
14:14 up 25 days, 22:09, 3 users, load averages: 1.96 2.38 3.19(1分,10分,15分的负载)
这个load averages的值理想值是=CPU的数目。当低于CPU数表示CPU有空闲,存在资源浪费。
多线程处理我们希望与cpu数目对齐,不让CPU空闲,就是这个意思。
我们一起分析
那多线程场景下,是不是创建线程越多越好呢?答案是不一定!
大家首先要明白一点在HotSpot VM线程模型中,线程被一对一映射到本地操作系统线程,JAVA线程启动会创建一个操作系统本地线程,新的线程需要分配CPU计算资源,切换也会带来资源的开销
这些个过程其成本其实是很大的。所以线程并非创建的越多越好。
那创建多少合适呢?面试官开始连环炮式问
其实还是分场景!主要分CPU密集型 VS I/O密集型两种。不同场景线程数的配置不一样。
CPU密集型:
当系统的硬盘、内存性能相对CPU要好很多。系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/内存),I/O在很短的时间就可以完成,而CPU还有许多运算要处理,CPU Loading很高。
我举个例子,拿我之前做的一个人脸识别项目来说,顾客通过刷脸行为我们后端人脸服务就能拿到对应的人脸数据,这个时候需要和底库数据(都存放在内存)比对,如果比对上证明当前这个人的存在(比对计算有一定的算法,需要靠CPU计算)。这个场景来刷一次脸就得比对一次,而且几乎没有涉及IO,就是典型的CPU密集型
I/O密集型:
系统的CPU性能相对硬盘、内存要好很多。此时,系统运作,大部分的状况是CPU在等I/O (硬盘/内存) 的读/写操作,此时CPU Loading并不高。
举个例子:消息中间件客服端应用就可以提高线程数,尽可能多的去拉取消息来进行处理。提高吞吐能力。
总结
CPU密集型程序:程序中进行大量的数据运算处理(在cpu资源足够的情况下,就可以同时处理,提高效率)
IO密集型程序:多任务并行处理(单磁盘可以并行压缩IO等待事件/多磁盘可以实现同时处理)
程序中大量进行IO操作,对cpu要求并不高因此执行流个数没有太大要求。
那各个场景创建多少线程合适呢?
CPU 密集型程序创建多少个线程合适?
最佳线程数 = cpu核心数+1: +1是为了预防有个线程被阻塞,cpu可以调用其他线程。
I/O密集型程序创建多少个线程合适?
最佳线程数 = (1/CPU利用率) = 1 + (I/O耗时/CPU耗时);(一般为2*CPU核心数)