我不明白的是:我们需要一个线程/处理程序来等待这些数据,
正确的?
并不真地。 NIO 背后的想法是任何线程都不会被阻塞。
这很有趣,因为操作系统已经以非阻塞方式工作。我们的编程语言是以阻塞方式建模的。
举个例子,假设您有一台带有单个 CPU 的计算机。您执行的任何 I/O 操作都会比 CPU 慢几个数量级,对吧?假设你想读取一个文件。你认为CPU会呆在那里,闲置,什么也不做,而磁盘头会去获取一些字节并将它们放入磁盘缓冲区吗?很明显不是。操作系统将注册一个中断(即回调),并同时将宝贵的 CPU 用于其他事情。当磁头成功读取几个字节并使其可供使用时,就会触发中断,操作系统会关注该中断,恢复之前的进程块并分配一些CPU时间来处理可用数据。
因此,在这种情况下,CPU 就像应用程序中的一个线程。它永远不会被阻止。它总是在做一些CPU密集型的事情。
NIO 编程背后的思想是相同的。在您公开的情况下,假设您的 HTTP 服务器有一个线程。当您收到来自客户端的请求时,您需要发出上游请求(代表 I/O)。因此,NIO 框架在这里要做的就是发出请求并在响应可用时注册回调。
之后,您宝贵的单线程立即被释放以处理另一个请求,该请求将注册另一个回调,依此类推。
当回调解析时,它将自动安排由您的单线程处理。
因此,该线程作为一个事件循环工作,您应该在其中仅调度 CPU 密集型内容。每次需要执行 I/O 时,都会以非阻塞方式完成,并且当 I/O 完成时,会将一些 CPU 绑定的回调放入事件循环中以处理响应。
这是一个强大的概念,因为使用非常少量的线程就可以处理数千个请求,因此可以更轻松地扩展。用更少的钱做更多的事。
此功能是其主要卖点之一Node.js以及为什么即使使用单线程也可以用来开发后端应用程序。
同样,这也是像这样的框架激增的原因Netty, RxJava, 反应流倡议和反应堆项目。他们都在寻求推广这种类型的优化和编程模型。
还有一种有趣的新框架运动,它们利用了这一强大的功能,并试图相互竞争或互补。我说的是有趣的项目,比如Vert.x and Ratpack。我很确定还有更多其他语言的。