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

Fre*_*ind 18 java nio

我找到了一些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);  
     }
 }
Run Code Online (Sandbox Code Playgroud)

当他获得所选择的密钥时,他会删除循环中的密钥.我们为什么要这样做?


UPDATE

感谢EJPuser270349提供的答案,我想我现在明白了,让我详细解释一下.

选择器中有2个表:

  1. 注册表:当我们打电话时channel.register,会有一个新项目(密钥)进入它.只有我们打电话key.cancel(),它才会从此表中删除.

  2. 准备选择表:当我们调用时selector.select(),选择器将查找注册表,找到可用的键,将它们的引用复制到该选择表.选择器不会清除此表的项目(这意味着,即使我们selector.select()再次调用,也不会清除现有项目)

这就是我们iter.remove()从选择表中获取密钥时必须调用的原因.如果没有,我们将一次又一次地获得密钥,selector.selectedKeys()即使它还没有准备好使用.

use*_*421 12

因为Selector永远不会这样做,所以它只会添加到集合中,所以如果你不这样做,你将在下次Selector返回时自己重新处理事件.