对我来说,以下是异步和非阻塞 I/O 最可能的定义:
Asynchronous I/O:
在异步 I/O 应用程序中,立即返回,操作系统会让它们知道字节何时可用于处理。
NON-blocking I/O:
这里应用程序立即返回可用的数据,并且应用程序应该具有轮询机制来找出更多数据何时准备就绪。
了解了这些定义后,如果我们分析java通道即
SocketChannel
、ServerSocketChannel
、DatagramSocketChannel
,我们可以发现这些通道可以通过configureBlocking(boolean block)
方法用作阻塞或非阻塞模式。并假设我们将它们用作非阻塞模式。那么问题来了:
如果我会使用
Selector
即将通道注册到selector
,无论它是异步 I/O 还是非阻塞 I/O?
我觉得当且仅当底层操作系统通知 java 应用程序有关通道的准备情况选择时,这才是 java 中的异步 I/O。否则它是非阻塞 I/O,并且
selector
只是一种帮助我们轮询上述通道的机制,正如我在定义中提到的那样。哪个是对的?预先感谢。
编辑:
我已经回答了问题的一部分,即 I/O 类型以及 java 如何促进这些功能。
但是还有一个问题,这些功能是由java提供的,是在java层模拟的,还是利用底层OS来实现的?假设底层操作系统支持这些功能。
请参考答案。
我想通过做更多的作业来回答我的问题。这篇文章还将有助于理解 I/O 概念。底层操作系统。
这是阻塞 I/O:
FileInputStream
、FileOutputStream
,甚至从 Socket 读取或写入也属于此类
这是非阻塞 I/O:这是由 Socket Channels 使用的,例如 Java 中的
ServerSocketchannel
、SocketChannel
、DatagramChannel
Selector
使用它来处理多个通道,这些通道本质上应该是 non-blocking
。因此,Socket 通道可以注册到 Selector
,并且 Selector
可以通过底层操作系统的 I/O 复用设施进行管理。AsynchronousSocketChannel
、AsynchronousServerSocketChannel
、AsynchronousFileChannel
促进。对于上述这些功能,java 大量使用底层操作系统。当我浏览书时,这一点很明显。作者在第四章提到了
真正的就绪选择必须由操作系统完成。操作系统执行的最重要功能之一是处理 I/O 请求并在数据准备就绪时通知进程。因此,只有将此功能委托给操作系统才有意义。 Selector 类提供了抽象,Java 代码可以通过该抽象以可移植的方式向底层操作系统请求就绪选择服务。
因此很明显,Java 大量使用底层操作系统来实现这些功能。
如果我将使用选择器,即将通道注册到选择器,无论是异步 I/O 还是非阻塞 I/O?
通道正在进行非阻塞 I/O。选择器本身正在执行“多路复用”I/O。 Java 中的异步 I/O 是通过 Futures 或 CompletionCallbacks 完成的,而在其他语言中则是通过信号量或回调完成的。
但是仍然存在一个问题,所有这些功能是由java提供的,是在java层模拟的,还是使用底层操作系统来实现的?假设底层操作系统支持这些功能。操作系统可以做到这一点。应用程序不能,而 Java 有资格作为操作系统的应用程序。