BIO、NIO、AIO understanding

1. What exactly are BIO, NIO, and AIO?

These can be understood as the encapsulation of various IO models of the operating system by the Java language. When using these APIs, programmers do not need to have knowledge about the operating system level, nor do they need to write different codes according to different operating systems. Just use the Java API.

2. The difference between BIO, NIO and AIO

1. BIO is the traditional java.io package (meaning that when you use the java.io package for input and output operations, you use the BIO communication mechanism), BIO is the traditional synchronous blocking I/O. That is to say, when reading the input stream or output stream, the thread will be blocked until the read and write operations are completed, and will occupy CPU resources until the read and write operations are completed before continuing to complete the following tasks.

The server using the BIO communication model usually has an independent Acceptor thread responsible for monitoring the connection of the client. After receiving the connection request from the client, it will create a new thread for each connection request of the client to process. After processing, The output stream is returned to the client, and the thread is destroyed. This is a typical request-response model.

 It can be seen that this is executed in a multi-threaded situation. Under single-threaded environment conditions, the server will call the accept method in the while loop to wait for the connection request from the client. Once the connection request is received, a socket can be established and read and write operations can be performed on the socket. To receive connection requests from other clients, you can only wait for the operation of the client connected to the current server to complete or the connection to be disconnected.

The biggest shortcoming of this model is the lack of elastic scalability. When the number of concurrent client accesses increases, the number of threads on the server and the number of concurrent client accesses are proportional to 1:1. Threads are a very valuable system for the Java virtual machine. Resources, when the number of threads expands, the performance of the system will drop sharply. As the amount of concurrency continues to increase, problems such as thread stack overflow and failure to create new threads will occur in the system, which will eventually cause the process to crash or freeze, and cannot be provided externally. Serve.

The code implemented by BIO:

public class server {
    private static Socket socket=null;
    public static void main(String[] args) {
        try {
            //绑定端口
            ServerSocket serverSocket=new ServerSocket();
            serverSocket.bind(new InetSocketAddress(8080));
            while (true){
                //等待连接  阻塞
                System.out.println("等待连接");
                socket = serverSocket.accept();
                System.out.println("连接成功");
                //连接成功后新开一个线程去处理这个连接
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        byte[] bytes=new byte[1024];
                        try {
                            System.out.println("等待读取数据");
                            //等待读取数据    阻塞
                            int length=socket.getInputStream().read(bytes);
                            System.out.println(new String(bytes,0,length));
                            System.out.println("数据读取成功");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2. NIO is the java.nio package introduced by Java 1.4. It provides new abstractions such as Channel, Selector, Buffer, etc., and can build multiplexed, synchronous non-blocking IO programs, while providing high performance closer to the bottom layer of the operating system data manipulation method. NIO achieves efficient processing by using a single thread to poll multiple connections, which can support a large number of concurrent connections, but the programming model is more complicated.

NIO is a communication model proposed to solve the defects of BIO. Take socket.read() as an example:

For socket.read() in the traditional BIO, if there is no data in the TCP RecvBuffer, the function will block until the data is received.

For NIO, if the TCP RecvBuffer has data, it will read the data from the network card to the memory and return it to the user; otherwise, it will return 0 directly and never block.

What BIO cares about is "I want to read", while NIO cares about "I can read".

An important feature of NIO is: the main read, write, register and receive functions of the socket are non-blocking during the ready stage, and the real I/O operations are synchronously blocked (consuming CPU but very high performance).

2.1 What is a Channel?

Channel, translated as "channel", is the pipeline for data transmission, similar to "flow", but different from "flow".

The difference between Channel and "stream":

  • It is possible to read data from the Channel and write data to the Channel, but the reading and writing of the stream is usually one-way - input and output stream
  • Channels can be read and written asynchronously
  • The data in the channel is always read to the buffer (buffer) first, or always needs to be written from a buffer, and the data cannot be accessed directly

2.2 What is Buffer?

Buffer is an object, which contains the data to be written or read. In the java.nio library, all data is processed by the buffer.

When reading data, it is directly read into the buffer; when writing data, it is also directly written into the buffer, and any time the data in the Channel is accessed, it is operated through the buffer.

A buffer is essentially an array, usually a byte array ByteBuffer, of course there are other types:

2.3 What is Selector? 

Selector is called a selector. Selector will continuously poll the Channel registered on it. If a read or write event occurs on a Channel, the Channel will be judged to be in the ready state and will be polled by the Selector, and then passed SelectionKey A collection of ready Channels can be obtained for subsequent I/O operations.

A multiplexer Selector can poll multiple Channels at the same time. JDK uses epoll() instead of the traditional select implementation, so there is no limit on the maximum connection handle, which means that only one thread is required to poll the Selector. You can access thousands of clients.

2.4 What is the relationship between Buffer, Selector, and Channel?

 2.5 Implementation of NIO multiplexing

NIO uses the mechanism of single-threaded polling events to decide what to do by efficiently locating the ready Channel. Only the select stage is blocked, which can effectively avoid the problems caused by frequent thread switching when a large number of clients connect. The ability to expand has been greatly improved.

  • First, create a Selector through Selector.open() to act as a dispatcher-like role;
  • Then, create a ServerSocketChannel, and register this Channel in the Selector, and tell the dispatcher through the specified SelectionKey.OP_ACCEPT that it is concerned with new connection requests;
  • Why do we need to explicitly configure non-blocking mode? This is because in blocking mode, the registration mode is not allowed, and IIIegalBlockingModeException will be thrown;
  • The Selector is blocked in the select operation, and will be woken up when an access request occurs in a Channel;
public class server {
    public static void main(String[] args) {
        try {
            //创建一个socket通道,并且设置为非阻塞的方式
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);//设置为非阻塞的方式
            serverSocketChannel.socket().bind(new InetSocketAddress(9000));
            //创建一个selector选择器,把channel注册到selector选择器上
            Selector selector = Selector.open();
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            while(true)
            {
                System.out.println("等待事件发生");
                selector.select();
                System.out.println("有事件发生了");
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while(iterator.hasNext())
                {
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    handle(key);
                }

            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static void handle(SelectionKey key) throws IOException{
        if(key.isAcceptable())
        {
            System.out.println("连接事件发生");
            ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
            //创建客户端一侧的channel,并注册到selector上
            SocketChannel socketChannel = serverSocketChannel.accept();
            socketChannel.configureBlocking(false);
            socketChannel.register(key.selector(),SelectionKey.OP_READ);
        } else if (key.isReadable()) {
            System.out.println("数据可读事件发生");
            SocketChannel socketChannel = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int len = socketChannel.read(buffer);
            if(len!=-1)
            {
                System.out.println("读取到客户端发送的数据:"+new String(buffer.array(),0,len));
            }
            //给客户端发送信息
            ByteBuffer wrap = ByteBuffer.wrap("hello world".getBytes());
            socketChannel.write(wrap);
            key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE);
            socketChannel.close();
        }
    }

The following is a flowchart of multiplexing:

 3. AIO is a package introduced after Java 1.7, which is an upgraded version of NIO. Asynchronous non-blocking I/O, realize efficient I/O operation through callback, that is, the application operation will return directly without blocking (at this time, the user process only needs to process data, and does not need to perform actual IO reading Write operation, because the real IO operation has been completed by the operating system kernel), when the background processing is completed, the operating system will notify the corresponding thread to perform subsequent operations. This can greatly reduce the consumption of system resources and is suitable for high-concurrency and high-throughput scenarios, but it may be limited by the operating system and hardware in actual use.

4. An example can be used to describe the difference between these three communication models: imagine a scenario where you want to boil water

BIO: During the boiling of the water, you have been standing by, not daring to do anything, and wait until the water boils before doing other things

NIO: You don’t have to stay by the side all the time during the boiling water, but check to see if the water is boiling from time to time, and you can do other things at other times

AIO: During the boiling process, you don’t need to check whether the water is boiling, you can complete other tasks. When the water is boiling, there will be a beep to remind you that the water is boiling, and you can deal with it at this time.

3. Supplements to some basic concepts

Synchronous and asynchronous (calls between threads):

During synchronous operation, the caller needs to wait for the callee to return the result before proceeding to the next step

Asynchronous is the opposite. The caller does not need to wait for the callee to return the call before proceeding to the next step. The callee usually relies on events, callbacks and other mechanisms to notify the caller to return the call result

Blocking and non-blocking (in-thread calls):

Blocking and non-blocking are for the same thread. At a certain moment, the thread is either blocked or non-blocked

Blocking and non-blocking focus on the status of the program while waiting for the call result (message, return value):

Blocking call means that the current thread will be suspended before the result of the call is returned, and the calling thread will not return until the result is obtained

A non-blocking call means that the call will not block the current thread until the result cannot be obtained immediately

IO is divided into two operations: the first step is to initiate an IO request, and the second step is to actually perform IO read and write operations

The concept of synchronous and asynchronous IO:

Synchronization means that after the user thread initiates an IO request, it waits or polls the kernel for the completion of the IO operation before continuing to execute subsequent code.

Asynchrony means that after the user thread initiates an IO request , it continues to execute subsequent code. When the kernel IO operation is completed, the user thread will be notified, or the callback function registered by the user thread will be called.

The concept of blocking and non-blocking IO:

Blocking means that IO read and write operations need to be completely completed before returning to user space

Non-blocking means that a status value is returned immediately after the IO read and write operation is called, without waiting for the IO operation to be completely completed

Four combinations:

References:

Analysis of the three major roles of Java NIO, Channel, Buffer, and Selector - Nuggets (juejin.cn) https://juejin.cn/post/7037028848487104519#heading-28 Detailed explanation of Channel in Java NIO - Nuggets (juejin.cn) https ://juejin.cn/post/7058948260529963039 Analysis and Understanding of BIO, NIO, and AIO in JAVA-Alibaba Cloud Developer Community (aliyun.com) https://developer.aliyun.com/article/726698#slide-26 Java Core (5) In-depth understanding of BIO, NIO, and AIO - Tencent Cloud Developer Community - Tencent Cloud (tencent.com) https://cloud.tencent.com/developer/article/1376675 Analysis of Java NIO - Zhihu ) https://zhuanlan.zhihu.com/p/23488863 Thorough understanding of synchronous asynchronous blocking non-blocking - LittleDonkey - Blog Park (cnblogs.com) https://www.cnblogs.com/loveer/p/11479249.html

Guess you like

Origin blog.csdn.net/qq_56919740/article/details/129966117