请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

selectionKey集合需要clear掉么?

...
//通过key存储的集合
private final Map<SelectionKey, Runnable> inputCallbackMap = new HashMap<>();
...
//塞入集合 
if (key == null) {
    try {
        //注册selector得到key
        key = channel.register(selector, registerOps);
        //根据key
        outputCallbackMap.put(key, callback);
    } catch (ClosedChannelException ignore) {
        return null;
    }
}
...
//调用handle,根据SelectionKey获取runnable进行回调
try {
    if (readSelector.select() == 0) {
        waitSelection(inRegInput);
        continue;
    }
    Set<SelectionKey> selectionKeys = readSelector.selectedKeys();
    for (SelectionKey selectionKey : selectionKeys) {
        if (selectionKey.isValid()) {
            handleSelection(selectionKey, SelectionKey.OP_READ, inputCallbackMap, inputHandlePool);
        }
    }
    selectionKeys.clear();//这里clear,把selectionKey都置空的是咋回事???
} catch (IOException e) {
    e.printStackTrace();
}

这边clear掉以后,再unRegister的时候,能remove掉对应的runnable么?

正在回答

1回答

哇,你差点吓到我了,我都被你的问句整蒙圈了。仔细看了一下,没啥毛病的。
selectionKeys.clear();

可以调用也可以不用调用,这个都不影响最终的数据情况。因为当我们循环下来的时候会再次调用:

Set<SelectionKey> selectionKeys = readSelector.selectedKeys();

得到这个集合,而这个selectedKeys();方法内部每次调用的时候其实本质都会进行clear后重新去copy一份当前就绪的副本的操作。


简单来说,就算你不进行clear操作,其内部也会发生类似的操作,让集合刷新。这是selector的根本,但其实这也是selector模式的性能瓶颈之一。

0 回复 有任何疑惑可以回复我~
  • 提问者 宝儿姐_ #1
    噢噢,就是selectedKeys(),相当于复制了一份ready的selectionKey的引用出来哦。明白了。
    回复 有任何疑惑可以回复我~ 2019-10-25 10:33:40
  • Qiujuer 回复 提问者 宝儿姐_ #2
    嗯嗯 可以理解为调用的时候,是被copy到了一个新的集合中;所以在新的集合中删除啥的都不影响真正的数据。
    回复 有任何疑惑可以回复我~ 2019-10-27 10:04:26
  • 提问者 宝儿姐_ #3
    非常感谢!
    回复 有任何疑惑可以回复我~ 2019-10-29 20:36:04
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信