使用nio 中 selectionKey.isReadable()造成 死循环

@Test
public void clientSocket() throws IOException {
    SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("localhost", 9999));

    socketChannel.configureBlocking(false);

    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);


    byteBuffer.put("你好好好好".getBytes());

    byteBuffer.flip();
    socketChannel.write(byteBuffer);
    byteBuffer.clear();

    socketChannel.shutdownOutput();
    socketChannel.close();


}

@Test
public void serverSocket() throws IOException {

    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    serverSocketChannel.configureBlocking(false);
    serverSocketChannel.bind(new InetSocketAddress(9999));

    Selector selector = Selector.open();

    // 注册连接事件
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

    while (selector.select() > 0) {
        Set<SelectionKey> selectionKeySet = selector.selectedKeys();
        System.out.println(selectionKeySet.size());
        Iterator<SelectionKey> iterator = selectionKeySet.iterator();
        while (iterator.hasNext()) {

            SelectionKey selectionKey = iterator.next();

            if (selectionKey.isAcceptable()) {
                System.out.println("accept=====");
                SocketChannel socketChannel = serverSocketChannel.accept();
                socketChannel.configureBlocking(false);

                socketChannel.register(selector, SelectionKey.OP_READ);
            } else if (selectionKey.isReadable()) {
                    
                System.out.println("read=====");
                SocketChannel socketChannel = (SocketChannel) selectionKey.channel();

                ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                socketChannel.read(byteBuffer);

                byteBuffer.flip();
                System.out.println(new String(byteBuffer.array()) + ":::::::::::::::::::");
                byteBuffer.clear();
            }

            iterator.remove();
            System.out.println(selectionKeySet.size());

        }
    }

}


在client结束后,我末尾打印的selectionKeySet.size()方法,本来是0,结果循环一遍siez却变成1了,仍然会不停的进入selectionKey.isReadable()方法,导致死循环


最后iterator应该是移除掉了,但集合里面总有一个SelectionKeyImp的对象,这个是哪里来的?


我末尾打印的selectionKeySet.size()方法,本来是0,结果循环一遍又

这是控制台:

1
[sun.nio.ch.SelectionKeyImpl@4b9e13df]
accept=====
0
1
[sun.nio.ch.SelectionKeyImpl@2b98378d]
read=====
你好好好好  
0
1
[sun.nio.ch.SelectionKeyImpl@2b98378d]
read=====       
    
0
1
[sun.nio.ch.SelectionKeyImpl@2b98378d]
read=====       
 
0
1
[sun.nio.ch.SelectionKeyImpl@2b98378d]
read=====     

0
1
[sun.nio.ch.SelectionKeyImpl@2b98378d]
read=====
慕粉4241372
浏览 2973回答 1
1回答
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java