netty5.x源码分析-EventLoopGroup和EventLoop

EventLoopGroup和EventLoop的建立

EventLoopGroup构造方法参数有两个一个是线程数一个是executor

  1. 若是不给线程数默认先读取系统变量io.netty.eventLoopThreads对应的值,若是没有则取cpu核数*2个
  2. 若是executor不给定则默认使用ForkJoinPool做为executor,并行数为上述值

先看一张NioEventLoopGroup继承图java

输入图片说明

###构造方法路径linux

NioEventLoopGroup->MultithreadEventLoopGroup->MultithreadEventExecutorGroupcentos

最终使用下面的代码,非关键代码不一一列举ide

private MultithreadEventExecutorGroup(int nEventExecutors,
                                          Executor executor,
                                          boolean shutdownExecutor,
                                          Object... args) {
        //1参数校验
        //2若是executor为空建立默认的ForkJoinPool
        //建立EventLoop
        children = new EventExecutor[nEventExecutors];

        for (int i = 0; i < nEventExecutors; i ++) {
            boolean success = false;
            try {

                //newChild方法在NioEventLoopGroup中实现,args是SelectorProvider
                children[i] = newChild(executor, args);
                success = true;
            } catch (Exception e) {
              
            } finally {
                
                //3若是不成功关闭全部的
            }
        }
        //4给EventLoop的终止增长回调函数
        //5把children变成只读
    }

NioEventLoopGroup中实现newChild方法函数

@Override
protected EventLoop newChild(Executor executor, Object... args) throws Exception {
    return new NioEventLoop(this, executor, (SelectorProvider) args[0]);
}

EventLoop继承关系图oop

输入图片说明

NioEventLoop.javathis

NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider) {
    super(parent, executor, false);
    if (selectorProvider == null) {
        throw new NullPointerException("selectorProvider");
    }
    provider = selectorProvider;
    selector = openSelector();
}

super中的第三个参数在SingleThreadEventExecutor构造函数中体现,当该值为true时,当且仅当调用addTask(Runnable)方法才会唤醒executor的线程,同时在SingleThreadEventExecutor构造方法中也建立了一个无界队列LinkedBlockingQueue<Runnable>()操作系统

回到NioEventLoop构造方法发现每建立一个EventLoop都会打开一个Selector。.net

总结

  1. EventLoopGroup从名字能够看出是用来建立和管理EventLoop。
  2. EventLoopGroup有不少种,通用的是NioEventLoopGroup,还有依赖操做系统支持的EpollEventLoopGroup,在linux系统下推荐使用EpollEventLoopGroup 回答的是netty in action的做者
  3. new一个EventLoopGroup的过程实际上就是一个建立多个EventLoop的过程
  4. 每建立一个EventLoop都要打开一个Selector,因此new的时候不要用过大的nThreads参数,EventLoop只负责读写数据,耗时的IO操做应该交给另外一个线程池来处理。
相关文章
相关标签/搜索