Netty源码分析 NioEventLoop的rebuildSelector方法解决Nio中select方法导致cpu100%的BUG

 


//重新创建Selector
public void rebuildSelector() {
    //判断是否是当前线程,如果是其它现成则加入队列,让单钱线程执行方法
    if (!inEventLoop()) {
        execute(new Runnable() {
            @Override
            public void run() {
                rebuildSelector0();
            }
        });
        return;
    }
    //内部方法
    rebuildSelector0();
}

private void rebuildSelector0() {
    //旧的选择器对象
    final Selector oldSelector = selector;

    //新的选择器对象
    final SelectorTuple newSelectorTuple;

    if (oldSelector == null) {
        return;
    }

    try {
        //创建一个新的选择器
        newSelectorTuple = openSelector();
    } catch (Exception e) {
        logger.warn("Failed to create a new Selector.", e);
        return;
    }


    // Register all channels to the new Selector.
    int nChannels = 0;
    //循环所有旧选择器上的key
    for (SelectionKey key: oldSelector.keys()) {

        //拿到key关联的对象
        Object a = key.attachment();
        try {
            //如果key无效 或者 channel已经关联到新选择器则循环下一个key
            if (!key.isValid() || key.channel().keyFor(newSelectorTuple.unwrappedSelector) != null) {
                continue;
            }

            //key之前绑定的事件类型
            int interestOps = key.interestOps();

            //把key取消
            key.cancel();

            //新的key,绑定到新的selector
            SelectionKey newKey = key.channel().register(newSelectorTuple.unwrappedSelector, interestOps, a);
            //如果之前key关联的对象时AbstractNioChannel,则更新key的引用为newKey
            if (a instanceof AbstractNioChannel) {
                // Update SelectionKey
                ((AbstractNioChannel) a).selectionKey = newKey;
            }
            nChannels ++;
        } catch (Exception e) {
            logger.warn("Failed to re-register a Channel to the new Selector.", e);
            if (a instanceof AbstractNioChannel) {
                AbstractNioChannel ch = (AbstractNioChannel) a;
                ch.unsafe().close(ch.unsafe().voidPromise());
            } else {
                @SuppressWarnings("unchecked")
                NioTask task = (NioTask) a;
                invokeChannelUnregistered(task, key, e);
            }
        }
    }

    //更新成员变量
    selector = newSelectorTuple.selector;
    unwrappedSelector = newSelectorTuple.unwrappedSelector;

    try {
        //关闭旧选择器
        // time to close the old selector as everything else is registered to the new one
        oldSelector.close();
    } catch (Throwable t) {
        if (logger.isWarnEnabled()) {
            logger.warn("Failed to close the old Selector.", t);
        }
    }

    if (logger.isInfoEnabled()) {
        logger.info("Migrated " + nChannels + " channel(s) to the new Selector.");
    }
}

 

你可能感兴趣的:(Netty)