为什么说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://juejin.cn/post/7184619435309662266

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值