Netty4源码分析—NioEventLoopGroup, NioEventLoop生成Selector_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Netty4源码分析—NioEventLoopGroup, NioEventLoop生成Selector

Netty4源码分析—NioEventLoopGroup, NioEventLoop生成Selector

 2013/11/5 18:36:42  bzhjian  程序员俱乐部  我要评论(1)
  • 摘要:真正实现生成selector的方法是在的NioEventLoopGroup的父类MultithreadEventExecutorGroup中MultithreadEventExecutorGroup(intnThreads,ThreadFactorythreadFactory,Object...args)方法参数:1、nThreads为线程数量,也就是nio中selector的数量,默认为CPU核数*2(DEFAULT_EVENT_LOOP_THREADS=Math.max(1
  • 标签:源码 net 分析 CTO

class="iteye-blog-content-contain">

??? 真正实现生成selector的方法是在的NioEventLoopGroup的父类MultithreadEventExecutorGroupMultithreadEventExecutorGroup(int nThreads, ThreadFactory threadFactory, Object... args)方法

?

参数:1nThreads线程数量,也就是nioselector的数量,默认为CPU核数*2

??? (DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt( "io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2))

?

??? 2ThreadFactory 线程工厂

?

??? 3args参数,这里的参数主要的是用于生成java nioSeletor的对象,这个参数我们没有传进去,Netty会自动判断并使用java.nio.channels.spi.SelectorProvider对象;

?

?

?? MultithreadEventExecutorGroup方法中主要的源码:

?

if (nThreads <= 0) {
            throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
        }
        if (threadFactory == null) {
            threadFactory = newDefaultThreadFactory();
        }
        children = new SingleThreadEventExecutor[nThreads];
        for (int i = 0; i < nThreads; i ++) {
            boolean success = false;
            try {
                children[i] = newChild(threadFactory, args);
                success = true;
            } catch (Exception e) {
                // TODO: Think about if this is a good exception type
                throw new IllegalStateException("failed to create a child event loop", e);
            } 

?? 这段代码中最主要的是newChild(threadFactory, args)这句话主要是生成了NioEventLoop对象,NioEventLoop对象调用openSelector方法生成了nio的选择器selector

private Selector openSelector() {
        final Selector selector;
        try {
            selector = provider.openSelector();
        } catch (IOException e) {
            throw new ChannelException("failed to open a new selector", e);
        }
        if (DISABLE_KEYSET_OPTIMIZATION) {
            return selector;
        }
        try {
            SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
            Class<?> selectorImplClass =
                    Class.forName("sun.nio.ch.SelectorImpl", false, ClassLoader.getSystemClassLoader());
            // Ensure the current selector implementation is what we can instrument.
            if (!selectorImplClass.isAssignableFrom(selector.getClass())) {
                return selector;
            }
            Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
            Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
            selectedKeysField.setAccessible(true);
            publicSelectedKeysField.setAccessible(true);
            selectedKeysField.set(selector, selectedKeySet);
            publicSelectedKeysField.set(selector, selectedKeySet);
            selectedKeys = selectedKeySet;
            logger.trace("Instrumented an optimized java.util.Set into: {}", selector);
        } catch (Throwable t) {
            selectedKeys = null;
            logger.trace("Failed to instrument an optimized java.util.Set into: {}", selector, t);
        }

        return selector;
}

?

??? 其中selector = provider.openSelector()负责生成seletor,这个方法后面的操作主要是通过反射优化Set类型的selectedKeys, publicSelectedKeys,因为在selector中这两个都不是线程安全的(没看selector源码,猜测而以),Netty自己使用实现Set接口SelectedSelectionKeySet代替原来的Set实现,防止在selectedKeyspublicSelectedKeys在读写时出现java.util.ConcurrentModificationException异常.


最后在绑定端口时,由ServerBootstrap的父类AbstractBootstrapinitAndRegiste方法调用NioEventLoopGroupregister方法将serversocketchannel注册到selector中并开始监听.

?

?

    1221122 2016/11/9 9:57:22 发表

    深入浅出Netty源码剖析 课程观看地址:http://.xuetuwuyou.com/course/157 课程出自学途无忧网:http://.xuetuwuyou.com

发表评论
用户名: 匿名