ITPub博客

首页 > 应用开发 > > 使用nio 中 selectionKey.isReadable()造成 死循环

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

作者:gamebus 时间:2019-07-17 10:36:46 0 删除 编辑
@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=====


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4687/viewspace-3130685/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-07-10

  • 博文量
    155
  • 访问量
    13187