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

标签 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);  
     }
 }

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


更新

感谢EJPuser270349的回答,我想我现在明白了,让我详细解释一下。

选择器中有2个表:

  1. registry table: 当我们调用channel.register时,会有一个新的item(key)进入它。只有当我们调用 key.cancel() 时,它才会从此表中删除。

  2. 准备选择表:当我们调用selector.select()时,选择器会查找注册表,找到可用的键,将它们的引用复制到这个选型表。这个表的项目不会被选择器清除(也就是说,即使我们再次调用selector.select(),它也不会清除现有的项目)

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

最佳答案

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

关于java - 为什么要在 java nio 的 `selector.selectedKeys().iterator()` 中删除 key ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7132057/

相关文章:

java - 在 Java Collections Map<Key,?> 中 "?"指的是什么?

java - 从我的 Java 应用程序中备份 MySql

java - 在android中使用CharacterBuffers时出现的错误

java - 将一定数量的字节读入 ByteBuffer

java - 如何扩展这个单线程 Java 客户端?

java - 将 int 转换为字节数组并使用 System.out.write 方法打印到控制台

java - 使用外部jar文件编译java程序

java - JDK 1.5 SSLHandshakeException

java - 通过 JDBC 使用结果集插入新行

java - 如何使用 FileChannel 和 ByteBuffer 从文件中写入和读取 Java 对象中的字符串属性