为什么在java nio的`selector.selectedKeys()。iterator()`中应该删除键?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (93)

我发现了一些java nio的示例代码:

 ServerSocketChannel server = ServerSocketChannel.open();  
 Selector selector = Selector.open();  
 server.socket().bind(new InetSocketAddress(8080));  
 server.configureBlocking(false); 
 server.register(selector, SelectionKey.OP_ACCEPT);  

 while(true) {
     selector.select(); 
     Iterator iter = selector.selectedKeys().iterator();  
     while (iter.hasNext()) {  
         SelectionKey key = (SelectionKey) iter.next();  
         iter.remove();  // Why remove it? 
         process(key);  
     }
 }

当他获得选定的键时,他会删除循环中的键。为什么我们应该这样做?

选择器中有两个表格:

  1. 注册表:当我们打电话时channel.register,会有一个新的项目(关键)进入它。只有我们打电话key.cancel(),它才会从这张表中删除。
  2. 准备好选择表:当我们调用时selector.select(),选择器将查找注册表,找到可用的键,将它们的引用复制到这个选择表中。这张表的项目不会被选择器清除(这意味着,即使我们selector.select()再次调用,它也不会清除现有项目)

这就是为什么iter.remove()当我们从选择表中获得密钥时必须调用。如果没有,selector.selectedKeys()即使没有准备好使用,我们也会一次又一次地获得密钥。

提问于
用户回答回答于

因为Selector从来不会这样做,所以它只会添加到集合中,所以如果您不这样做,您将在Selector下次返回时重新处理事件。

用户回答回答于

因为直到你做它,你无法检测到新的事件重复。

扫码关注云+社区