我找到了一些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);
}
}
当他获得选定的键时,他会在循环中删除键。为什么我们应该这样做?
更新
感谢EJP和user270349的回答,我想我现在明白了,让我详细解释一下。
选择器中有2个表:
registry table: 当我们调用
channel.register
时,会有一个新的item(key)进入它。只有当我们调用key.cancel()
时,它才会从此表中删除。准备选择表:当我们调用
selector.select()
时,选择器会查找注册表,找到可用的键,将它们的引用复制到这个选型表。这个表的项目不会被选择器清除(也就是说,即使我们再次调用selector.select()
,它也不会清除现有的项目)
这就是为什么我们必须在从选择表中获取 key 时调用 iter.remove()
的原因。如果没有,我们将通过 selector.selectedKeys()
一次又一次地获取 key ,即使它还没有准备好使用。
最佳答案
因为选择器从不这样做,它只会添加到集合中,所以如果您不这样做,您将在下次选择器返回时自己重新处理事件。
关于java - 为什么要在 java nio 的 `selector.selectedKeys().iterator()` 中删除 key ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7132057/