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模型之间的映射关系如下:

  1. 阻塞式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
    14
    ServerSocketChannel 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();
    }
  2. 非阻塞式I/O模型

    Java的I/O类库可以使用非阻塞式I/O模型。在该模型下,I/O操作会立即返回,不会阻塞,但此时数据可能还没有准备好或者操作没有完成。需要使用轮询的方式检查操作是否完成。对应的系统I/O模型是非阻塞式I/O模型。主要对应的系统I/O模型是Linux系统中的select()或poll()函数
    java中主要是通过selector轮询socket的事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Selector selector = Selector.open();
ServerSocketChannel server = ServerSocketChannel.open();
server.socket().bind(new InetSocketAddress(8080));

// 将其注册到 Selector 中,监听 OP_ACCEPT 事件
server.configureBlocking(false);
server.register(selector, SelectionKey.OP_ACCEPT);

while (true){
int readyChannels=selector.select();
if(readyChannels==0){
continue;
}
doSomething();
}
  1. 选择器模型

    Java的NIO(New I/O)类库提供了选择器模型,它支持同时管理多个I/O操作。在该模型下,可以使用一个线程同时管理多个通道,每个通道上可以注册多个I/O操作,并且可以检查这些操作是否已经准备好或者完成。主要对应的系统I/O模型是Linux系统中的epoll模型和FreeBSD系统中的kqueue模型

    这个主要是java各种Nio包里的非Async开头的channel实现的

  2. 异步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模型对应的系统函数:

  1. 阻塞式I/O模型
    • Linux/Unix: read(), write()
    • Windows: ReadFile(), WriteFile()
  2. 非阻塞式I/O模型
    • Linux/Unix: fcntl() 或 ioctl(),也可以使用select()或poll()函数
    • Windows: ioctlsocket(),也可以使用select()或WSAPoll()函数
  3. 选择器模型
    • Linux/Unix: epoll_wait() 或者 select()
    • Windows: select() 或者 WSAEventSelect()
  4. 异步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模型

https://heyfl.gitee.io/system/IO-model2.html

作者

神奇宝贝大师

发布于

2020-10-18

更新于

2021-12-25

许可协议

评论