selectionKey集合需要clear掉么?

来源:7-11 NIO服务器Thread优化-5

宝儿姐_

2019-10-22

...
//通过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回答

Qiujuer

2019-10-25

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

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

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

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


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

0
3
宝儿姐_
非常感谢!
2019-10-29
共3条回复

Socket网络编程进阶与实战 系统掌握Socket核心技术

理论+实践,系统且深入掌握Socket核心技术,从容应对各种Socket应用场景的不二之选

2314 学习 · 476 问题

查看课程