为什么要在java nio的`selector.selectedKeys()。iterator()`中删除键?
导读:如何解决为什么要在java nio的`selector.selectedKeys()。iterator()`中删除键??由于选择器从不执行此操作,因此只会添加到集合中,因此,如果不这样做,则下次选择器返回时,您将自己重新处理事件。解决方法 ...
由于选择器从不执行此操作,因此只会添加到集合中,因此,如果不这样做,则下次选择器返回时,您将自己重新处理事件。
解决方法我发现了一些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个表:
登记表:当我们呼叫时channel.register,其中会有一个新的项目(密钥)。仅当我们调用时key.cancel(),它将从此表中删除。
准备好选择表:当我们调用时selector.select(),选择器将查找注册表,找到可用的键,并将它们的引用复制到该选择表中。选择器不会清除此表中的项目(这意味着,即使我们selector.select()再次调用,它也不会清除现有项目)
这就是为什么iter.remove()当我们从选择表中获得键时必须调用的原因。如果没有,selector.selectedKeys()即使它尚未准备好使用,我们也会一次又一次地获得密钥。
相关文章:
1. 从Spring MVC XML文件移动到javaconfig。我的数据库XML文件真的让我迷茫了2. vagrant - 使用NFS文件夹作为mysql datadir无法启动mysql的问题?3. Java中的枚举。优点?4. python - django的model字段在保存的时候做预处理怎么办?5. 试图使使用OpenCV的Java应用程序(可执行Jar)可移植。收到不满意的链接错误6. Java。按值对地图排序7. Java泛型问题:类“不在类型变量的范围内”错误。8. Java。HSSF。Apache-poi。如何修改代码9. 为什么在java中,赋值和数据类型一样的变量i3,i4,System.out.println(i3==i4),最终输出不相等?10. AngularJs。是否可以通过单击取消选择HTML“广播”输入?