首页 > 解决方案 > CPU 是否会在因 IO 读/写而阻塞的 Java 线程上浪费时间?

问题描述

如果一个线程在向 IO 写入数据时被阻塞,CPU 是否需要随时给这个线程,直到这个 IO 操作完成?

如果是这样,为什么要放弃 CPU?

如果不是,除了“每个线程的堆栈”之外,还有什么东西使“每个线程的请求”在重负载下的性能不如“具有共享线程的非阻塞 IO”?

PS:我已经阅读了很多关于这个主题的 SO 问题,我找不到解决这个特定方面的答案

标签: javamultithreadingiononblocking

解决方案


如果一个线程在向 IO 写入数据时被阻塞,CPU 是否需要随时给这个线程,直到这个 IO 操作完成?

不,操作系统只会将等待再次运行的线程出列并恢复它。

如果不是,除了“每个线程的堆栈”之外,还有什么东西使“每个线程的请求”在重负载下的性能不如“具有共享线程的非阻塞 IO”?

让一个等待线程出队并恢复它对于一个线程来说可能很便宜,但是当你有数千个线程时它并不便宜。不要忘记操作系统必须计算恢复哪个线程(根据优先级),在哪里恢复它(根据可用的 CPU 和亲和性),并且 CPU 本身可能必须将线程使用的内存加载到缓存行,这是一个真正的婊子。

更不用说进入睡眠状态的线程必须将其数据从缓存行刷新到 RAM 本身,这是一项非常昂贵的操作(缓存行存在是有原因的,一个很大的原因)。

是的,数千个线程消耗的内存会占用大量内存,从而减慢整个系统的速度。

现在,并不是说 HTTP 服务器只使用线程和阻塞 IO 就不能很好地执行,但是由于今天使用异步操作(使用期货、异步/等待、回调)非常容易,我们只是更喜欢服务器的异步 IO实际上需要速度。


推荐阅读