netty NioEventLoop的selectedKeys是在哪里修改的

问题产生的原因

查看netty源码时,理解NioEventLoop中的run方法主要负责轮询监听就绪的 I/O事件,流程就三个步骤:
1、轮询 Selector 选择器中已经注册的所有 Channel 的 I/O 事件。select()方法
2、处理已经准备就绪的 I/O 事件。 processSelectedKeys()方法
3、处理任务队列中的非 I/O 任务。runAllTasks()方法
其中第一步就是循环查找是否有需要处理的任务,当接收到任务时,则去处理。进入第二步时,代表存在任务。即进入processSelectedKeys()方法。内容如下

private void processSelectedKeys() {
        if (selectedKeys != null) {
            processSelectedKeysOptimized();
        } else {
            processSelectedKeysPlain(selector.selectedKeys());
        }
    }

而由于selectedKeys,一般在该类初始化时被赋值了(构造函数NioEventLoop(...)中调用了openSelector()方法,该方法中存在赋值操作selectedKeys = selectedKeySet;),不可能为null。然而我在debug的时候,自己连入服务端时经常里面没有对象,然后过一段时间又有了。故存在疑惑,哪里给它赋值的。

问题解决

1、搜索selectedKeys出现的地方(alt+f7),发现只在NioEventLoop中出现。涉及赋值操作的只有上面说的那一步。
netty NioEventLoop的selectedKeys是在哪里修改的_第1张图片
2、所以现在目标改为查询selectedKeySet,该对象在openSelector()方法中创建,在如下地方使用了。
openSelector()方法中
netty NioEventLoop的selectedKeys是在哪里修改的_第2张图片

//  openSelector() 中 unwrappedSelector 的创建
final Selector unwrappedSelector;
try {
    // 这个provider 是  NioEventLoop()中调用SelectorProvider.provider()产生的。我这是windows,所以是WindowsSelectorImpl
     unwrappedSelector = provider.openSelector();
 } catch (IOException e) {
     throw new ChannelException("failed to open a new selector", e);
 }

==在openSelector()方法中最终用unwrappedSelector调用了SelectorTuple的构造方法返回了,最终NioEventLoop中的selectorunwrappedSelector与其有关系。

//  openSelector()
return new SelectorTuple(unwrappedSelector,new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet));
// selector 和 unwrappedSelector这两个私有属性使用了
final SelectorTuple selectorTuple = openSelector();
selector = selectorTuple.selector;
unwrappedSelector = selectorTuple.unwrappedSelector;                                 

3、现在可知只有selectorunwrappedSelector与我们想找的selectedKeys的有关。具体点,就是selector 包装了unwrappedSelector,而unwrappedSelector中两个属性被selectedKeys替换了。进入SelectorImpl类(WindowsSelectorImpl > SelectorImpl > AbstractSelector > Selector),它的两个私有属性selectedKeyspublicSelectedKeys被修改了,现在与我们所找的selectedKeys是同一个。所以最终我们就只需要看这两个属性哪里被使用了就行。
注意,这里不单单找当前类中使用者两个属性的地方,还要在它的父类找。我这里没注意卡了好久
4、WindowsSelectorImpl中查询,在processFDSet()方法中发现修改值。
netty NioEventLoop的selectedKeys是在哪里修改的_第3张图片

整体梳理

NioEventLoop 创建

netty NioEventLoop的selectedKeys是在哪里修改的_第4张图片

NioEventLoop启动

netty NioEventLoop的selectedKeys是在哪里修改的_第5张图片

NioEventLoop中selectedKeys属性修改流程

netty NioEventLoop的selectedKeys是在哪里修改的_第6张图片

额外内容

对java nio不太懂得可以看下

你可能感兴趣的:(java,奇奇怪怪的问题,java,netty)