写点什么

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

  • 2023-01-03
    湖南
  • 本文字数:879 字

    阅读完需:约 3 分钟

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

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 密集型的请求。

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

原文:https://mp.weixin.qq.com/s/XeLdBrcZxhyMyIzu8QMGVg

如果感觉本文对你有帮助,点赞关注支持一下,想要了解更多 Java 后端,大数据,算法领域最新资讯可以关注我公众号【架构师老毕】私信 666 还可获取更多 Java 后端,大数据,算法 PDF+大厂最新面试题整理+视频精讲

用户头像

需要资料添加小助理vx:bjmsb2020 2021-10-19 加入

爱生活爱编程

评论

发布
暂无评论
为什么说IO密集型业务,线程数是CPU数的2倍?_程序员_Java永远的神_InfoQ写作社区