Java I/O模型与系统I/O模型
[原创]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/system/IO-model2.html
接: IO模型
Java I/O模型与系统I/O模型的映射关系
Java的I/O模型是建立在底层系统I/O模型之上的,它通过对底层系统I/O调用的封装,提供了更高层次的抽象和统一的I/O接口。Java的I/O类库支持的I/O模型和底层系统I/O模型之间的映射关系如下:
阻塞式I/O模型
Java的I/O类库默认使用阻塞式I/O模型。在该模型下,I/O操作会一直阻塞,直到数据准备好或者操作完成才返回。对应的系统I/O模型是传统的阻塞式I/O模型。主要对应的系统I/O模型是Linux系统中的read(), write()
这里主要是各种Stream、Reader、Writer、Socket的读写,其中Socket为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 监听 8080 端口进来的 TCP 链接
serverSocketChannel.socket().bind(new InetSocketAddress(8080));
while (true) {
// 这里会阻塞,直到有一个请求的连接进来
SocketChannel socketChannel = serverSocketChannel.accept();
// 开启一个新的线程来处理这个请求,然后在 while 循环中继续监听 8080 端口
SocketHandler handler = new SocketHandler(socketChannel);
new Thread(handler).start();
}非阻塞式I/O模型
Java的I/O类库可以使用非阻塞式I/O模型。在该模型下,I/O操作会立即返回,不会阻塞,但此时数据可能还没有准备好或者操作没有完成。需要使用轮询的方式检查操作是否完成。对应的系统I/O模型是非阻塞式I/O模型。主要对应的系统I/O模型是Linux系统中的select()或poll()函数
java中主要是通过selector轮询socket的事件:
1 | Selector selector = Selector.open(); |
选择器模型
Java的NIO(New I/O)类库提供了选择器模型,它支持同时管理多个I/O操作。在该模型下,可以使用一个线程同时管理多个通道,每个通道上可以注册多个I/O操作,并且可以检查这些操作是否已经准备好或者完成。主要对应的系统I/O模型是Linux系统中的epoll模型和FreeBSD系统中的kqueue模型
这个主要是java各种Nio包里的非Async开头的channel实现的
异步I/O模型
Java的AIO(Asynchronous I/O)类库提供了异步I/O模型,它支持在I/O操作完成时通知应用程序。在该模型下,可以异步地提交I/O操作,I/O操作的完成时会通过回调函数通知应用程序。主要对应的系统I/O模型是Windows系统中的I/O Completion Port模型
这个主要是在各种Asynchronous***Channel实现
注: Java的I/O类库是跨平台的,因此在不同的操作系统上可能使用不同的底层系统I/O模型
例如,在Linux上使用Java的I/O类库默认会使用epoll模型,在Windows上则会使用I/O Completion Port模型
系统各个I/O模型对应的函数
不同的操作系统实现I/O模型的方式可能不同,因此每种I/O模型对应的系统函数也会有所不同。下面是常见的操作系统中,各个I/O模型对应的系统函数:
- 阻塞式I/O模型
- Linux/Unix: read(), write()
- Windows: ReadFile(), WriteFile()
- 非阻塞式I/O模型
- Linux/Unix: fcntl() 或 ioctl(),也可以使用select()或poll()函数
- Windows: ioctlsocket(),也可以使用select()或WSAPoll()函数
- 选择器模型
- Linux/Unix: epoll_wait() 或者 select()
- Windows: select() 或者 WSAEventSelect()
- 异步I/O模型
- Linux/Unix: io_submit() 或者 aio_read()
- Windows: WSASend() 或者 WSARecv()
需要注意的是,Java的I/O类库是跨平台的,因此它使用的系统函数可能会因操作系统而异
Java的I/O类库是建立在底层系统I/O模型之上的,因此它可以使用操作系统提供的任何I/O模型对应的函数来实现I/O操作
Java I/O模型与系统I/O模型