Netty中NioEventLoop源码分析

版本

本次源码分析基于Netty的版本为4.1

源码分析

NioEventLoop可以视为java中的一个线程,只不过NioEventLoop处理的事件,以及内部的处理逻辑会有所不同。先看一下类的继承关系:

可以看到NioEventLoop实现了很多接口,特别是EventLoop和ScheduledExecutorService,所以NioEventLoop不仅能实现普通的task,还能实现定时task。

Selector

Netty的实现是基于Java原生的NIO的,其对原生的NIO做了很多优化,避免了某些bug,也提升了很多性能。但是底层对于网络IO事件的监听和处理也是离不开多路复用器Selector的。在NioEventLoop的构造方法中进行了Selector的初始化:

final SelectorTuple selectorTuple = openSelector();
selector = selectorTuple.selector;

关键还是openSelector()方法,这里我删除了一些分支代码,剩下的做了注释,其中常量 DISABLEKEYSET_OPTIMIZATION 的定义如下,可以手工配置是否开启优化,默认是开启优化的,具体优化做了什么事可以查看下面的openSelector()分析。

private static final boolean DISABLE_KEY_SET_OPTIMIZATION = SystemPropertyUtil.getBoolean("io.netty.noKeySetOptimization", false);

netty在创建selector的时候就尝试了优化,具体优化其实是将底层的数据结构从HashSet改为了数组,可以从SelectedSelectionKeySet和SelectorImpl的源码看到这一点,这里就不列了。

private SelectorTuple openSelector() {
    final Selector unwrappedSelector;
    try {
        // 根据底层的IO模型来创建一个selector,这里的selector就是java中NIO的selector
        unwrappedSelector = provider.openSelector();
    } catch (IOException e) {
        throw new ChannelException("failed to open a new selector", e);
    }
    // 如果未开启优化则直接就返回了,SelectorTuple可以视为一个持有selector引用的句柄
    if (DISABLE_KEY_SET_OPTIMIZATION) {
        return new SelectorTuple(unwrappedSelector);
    }

    Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {
        @Override
        public Object run() {
            try {
                // 通过反射创建一个selector的具体实例
                return Class.forName(
                        "sun.nio.ch.SelectorImpl",
                        false,
                        PlatformDependent.getSystemClassLoader());
            } catch (Throwable cause) {
                return cause;
            }
        }
    });

    final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
    // netty自己包装的一个selectKey的集合类
    final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();

    Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
        @Override
        public Object run() {
            try {
                Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
                Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");

                if (PlatformDependent.javaVersion() >= 9 && PlatformDependent.hasUnsafe()) {
                    // java 9 以上版本会用Unsafe类直接底层替换SelectionKeySet
                }
                // 利用反射将原生selector中的两个属性替换为netty自己的包装类
                selectedKeysField.set(unwrappedSelector, selectedKeySet);
                publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);
                return null;
            } catch (NoSuchFieldException e) {
                return e;
            } catch (IllegalAccessException e) {
                return e;
          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值