Verifique o modelo sem bloqueio do NIO

Sabemos que o modelo BIO tradicional é bloqueado ao aguardar a conexão do cliente. Se não houver dados durante a leitura dos dados, ele também é bloqueado, enquanto o NIO pode ser configurado para ser sem bloqueio. Sem mais delongas, basta olhar para o código:

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();
                }
            }
        }
    }
}
//Não-bloqueio do lado do servidor 
serverSocketChannel.configureBlocking(false); 
//Não-bloqueio do lado do cliente 
client.configureBlocking(false);

Essas duas linhas de código são muito importantes. serverSocketChannel.configureBlocking(false) é definido como true. Então, enquanto não houver conexão do cliente, SocketChannel client = serverSocketChannel.accept(); esta linha será bloqueada e não será impressa a cada segundo. Não "Há uma nova conexão de cliente....."

Até que um cliente esteja conectado via telnet:

No entanto, ele ainda continuará bloqueando e aguardando a próxima conexão do cliente. Restauramos a linha serverSocketChannel.configureBlocking(false) para false, definimos client.configureBlocking(false); como true e vemos o efeito:

Após a conexão do primeiro cliente, os dados devem ser inseridos, caso contrário a leitura estará sempre bloqueada.

Vamos retornar ambas as opções para false e, em seguida, jogá-las no sistema Linux para executar e ver as chamadas do sistema (como verificar as chamadas do sistema, há um artigo anterior sobre modelo BIO Modelo BIO em Java - blog CSDN ) :

Você pode ver que accept não bloqueia como NIO, mas retorna diretamente -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

Na verdade, esta linha gera a frase "Há uma nova conexão de cliente..."

Acho que você gosta

Origin blog.csdn.net/qq_17805707/article/details/133384859
Recomendado
Clasificación