Verify NIO’s non-blocking model

We know that the traditional BIO model is blocked when waiting for the client to connect. If there is no data when reading data, it is also blocked, while NIO can be configured to be non-blocking. Without further ado, just look at the code:

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class NioServer {
    public static void main(String[] args) throws Exception {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //服务端非阻塞
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(8888));
        List<SocketChannel> clients = new LinkedList<>();
        while (true) {
            TimeUnit.SECONDS.sleep(1);
            SocketChannel client = serverSocketChannel.accept();
            if (null == client) {
                System.err.println("没有新的客户端连接.....");
            } else {
                //客户端非阻塞
                client.configureBlocking(false);
                System.err.println(client.socket());
                clients.add(client);
            }
            ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
            for (SocketChannel socketChannel : clients) {
                int num = socketChannel.read(byteBuffer);
                if (num > 0) {
                    byteBuffer.flip();
                    byte[] bytes = new byte[byteBuffer.limit()];
                    byteBuffer.get(bytes);
                    String b = new String(bytes);
                    System.err.println(b);
                    byteBuffer.clear();
                }
            }
        }
    }
}
//Server-side non-blocking
serverSocketChannel.configureBlocking(false);
//client non-blocking
client.configureBlocking(false);

These two lines of code are very important. serverSocketChannel.configureBlocking(false) is set to true. Then as long as there is no client connection, SocketChannel client = serverSocketChannel.accept(); this line will block and will not print every second. No "There is a new client connection....."

Until a client is connected via telnet:

However, it will still continue to block and wait for the next client connection. We restore the serverSocketChannel.configureBlocking(false) line to false, set client.configureBlocking(false); to true, and see the effect:

After the first client is connected, data must be entered, otherwise read will always be blocked.

Let’s return both options to false, and then run them on the Linux system to see the system calls (how to check the system calls, there is a previous article on the BIO model: BIO model in Java - CSDN blog ) :

You can see that accept does not block like NIO, but directly returns -1, write(2, "\346\262\241\346\234\211\346\226\260\347\232\204\345 \256\242\346\210\267\347\253\257\350\277\236\346\216\245....", 32) = 32

This line actually outputs the sentence "There is a new client connection..."

Guess you like

Origin blog.csdn.net/qq_17805707/article/details/133384859