为什么说IO密集型业务,线程数是CPU数的2倍?

开发
I/O请求的速度,要远低于CPU运行的速度。大部分I/O请求,在发起之后,就进入等待状态,这个等待状态不会浪费CPU,所以一台机器在同一时刻支持的I/O请求,可以很多。

I/O密集型业务,线程数量要设置成 CPU 的 2 倍!

也不知道这是哪本书的坑爹理论,现在总有一些小青年老拿着这样的定理来说教。说的信誓旦旦,毋庸置疑,仿佛是权威的化身。讨论时把这样的理论当作前提,真的是受害不浅。

但可惜的是,这样的理论站不住脚。我只需要一个简单的反问,它就不攻自破:

Tomcat的默认线程数是多少呢?

它既不是 CPU 的 2 倍,也不是什么其他数值。在某些高并发的服务中,它的核心线程数,可能达到数千甚至上万。对于一个Tomcat来说,它处理的大多数都是I/O密集型的业务,可以说是最好的实践场景。

要明白这个线程数设置的玄机,就必须了解I/O请求的特点。I/O请求不仅仅指的是磁盘读写,在互联网服务中更多指的是网络I/O请求。

I/O请求的速度,要远低于CPU运行的速度。大部分I/O请求,在发起之后,就进入等待状态,这个等待状态不会浪费CPU,所以一台机器在同一时刻支持的I/O请求,可以很多。

如果I/O请求的速度比较快,和CPU的耗时对等的时候,我们把处理I/O的线程数,设置成 CPU 的 2倍,是合理的。但现实中并没有这么多如果,我们要处理秒成千上万的I/O请求,注定了它的耗时要比CPU多的多。

像RPC组件,比如Dubbo服务端,也会设置一个比较大的线程数(比如600);Feign这种就更不用多说了,短连接意味着更多线程数的支持。这都是些最佳实践。

虽然I/O线程数量增多,会造成非常频繁的上下文切换,进而影响效率。但在互联网应用中,它却是一个优秀的解决方案。

更优秀的解决方式也有,那就是使用协程。协程是用户态的线程,是对普通线程更细粒度的划分。它是在用户态运行的,由用户自行调度,所以也就避免了频繁的上下文切换问题。

但协程在Java中还不成熟,它依然是Golang语言的诱人特性。使用Golang开发的Web服务,可以采用更少的线程来支持大量I/O密集型的请求。

综上所述,标题的表述并不正确,而且错的离谱。

作者简介:小姐姐味道  (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。

责任编辑:武晓燕 来源: 小姐姐味道
相关推荐

2020-09-07 07:33:01

NodejsCPU密集型

2023-08-09 09:03:49

CPU密集型运算

2018-03-22 09:16:06

密集型场景SSD

2021-07-20 08:12:55

CPU核数线程数

2011-11-11 09:11:09

云计算HPC集群

2020-09-09 16:20:16

区块链比特币数字货币

2019-06-04 15:18:30

Web ServerNginx中间件

2012-10-08 09:45:22

数据密集型处理系统

2022-06-27 14:01:31

LZ4 分析数据密集型压缩算法

2024-02-26 08:28:24

Java线程CPU

2012-12-14 11:00:02

VDI桌面虚拟化

2012-12-17 11:20:51

VDI桌面虚拟化

2011-11-14 13:29:22

移动应用开发移动开发移动互联网

2021-02-23 08:02:23

线程volatileinterrupt

2023-09-18 08:01:06

Spring管理Mybatis

2010-04-14 15:30:41

Oracle数据库

2013-08-15 15:24:07

戴尔

2021-04-22 07:47:46

Linux进程管理

2024-05-06 08:17:50

线程池机制线程数

2022-03-14 08:33:09

TypeScriptJavaScript前端
点赞
收藏

51CTO技术栈公众号