• Netty源码分析第2章(NioEventLoop)---->第2节: NioEventLoopGroup之NioEventLoop的创建


     

    Netty源码分析第二章: NioEventLoop

     

    第二节: NioEventLoopGroup之NioEventLoop的创建

     

    回到上一小节的MultithreadEventExecutorGroup类的构造方法:

    protected MultithreadEventExecutorGroup(int nThreads, Executor executor, 
                                            EventExecutorChooserFactory chooserFactory, Object... args) {
        //代码省略
        if (executor == null) {
            //创建一个新的线程执行器(1)
            executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
        }
        //构造NioEventLoop(2)
        children = new EventExecutor[nThreads];
        for (int i = 0; i < nThreads; i ++) {
            boolean success = false;
            try {
                children[i] = newChild(executor, args);
                success = true;
            } catch (Exception e) {
                throw new IllegalStateException("failed to create a child event loop", e);
            } finally {
               //代码省略
            }
        }
        //创建线程选择器(3)
        chooser = chooserFactory.newChooser(children);
        //代码省略
    }

    我们来看第二步构造NioEventLoop:

    这里通过 children = new EventExecutor[nThreads] 初始化了children属性, 看下这个属性的定义:

    private final EventExecutor[] children

    这里的childrenEventExecutor类型的数组, 其实就是NioEventLoop的集合, 因为NioEventLoop也是EventExecutor的子类

    所以这里初始化了children数组, 大小为参数nThreads传入的线程数量, 默认为cpu核数的两倍

    后面就是通过for循环来创建NioEventLoop线程,

    在循环体里通过 children[i] = newChild(executor, args) 创建NioEventLoop, 我们跟newChild(executor, args)方法

    因为是NioEventLoopGroup调用的,所以跟到NioEventLoopnewChild方法中:

    protected EventLoop newChild(Executor executor, Object... args) throws Exception {
        return new NioEventLoop(this, executor, (SelectorProvider) args[0], 
            ((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);
    }

    这里我们看到创建了一个NioEventLoop对象, 其中thisNioEventLoopGroup自身, executor就是上一小节讲到的线程执行器

    我们继续跟到NioEventLoop的构造方法:

    NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider, 
                 SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) {
        super(parent, executor, false, DEFAULT_MAX_PENDING_TASKS, rejectedExecutionHandler);
        //代码省略
        provider = selectorProvider;
        selector = openSelector();
        selectStrategy = strategy;
    }

    首先看到了调用了父类的构造方法, 然后初始化了几个属性:

     selector = openSelector() 这种方式创建个NioEventLoop绑定的selector对象, 有关创建过程, 之后会讲到

    跟进父类SingleThreadEventLoop类构造方法:

    protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor, 
                                    boolean addTaskWakesUp, int maxPendingTasks, 
                                    RejectedExecutionHandler rejectedExecutionHandler) {
        super(parent, executor, addTaskWakesUp, maxPendingTasks, rejectedExecutionHandler);
        tailTasks = newTaskQueue(maxPendingTasks);
    }

    再跟到父类SingleThreadEventExecutor构造方法:

    protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor, 
                                        boolean addTaskWakesUp, int maxPendingTasks, 
                                        RejectedExecutionHandler rejectedHandler) {
        super(parent);
        this.addTaskWakesUp = addTaskWakesUp;
        this.maxPendingTasks = Math.max(16, maxPendingTasks);
        this.executor = ObjectUtil.checkNotNull(executor, "executor");
        taskQueue = newTaskQueue(this.maxPendingTasks);
        rejectedExecutionHandler = ObjectUtil.checkNotNull(rejectedHandler, "rejectedHandler");
    }

     this.executor = ObjectUtil.checkNotNull(executor, "executor") 这里初始化了线程执行器

     taskQueue = newTaskQueue(this.maxPendingTasks) 是创建一个任务队列, 这个任务队列可以将不属于NioEventLoop线程的任务放到这个任务队列中, 通过NioEventLoop线程执行, 具体使用场景之后我们会看到

     

    跟到父类AbstractScheduledEventExecutor的构造方法中:

    protected AbstractScheduledEventExecutor(EventExecutorGroup parent) {
        super(parent);
    }

    继续跟进去, 最后跟到AbstractEventExecutor类的构造方法:

    protected AbstractEventExecutor(EventExecutorGroup parent) {
        this.parent = parent;
    }

    这里初始化了parent, 这个parentNioEventLoop所属的线程组NioEventLoopGroup对象

    至此, NioEventLoop创建完成

     

     

    上一节: NioEventLoopGroup之创建线程执行器

    下一节: 初始化线程选择器

  • 相关阅读:
    软件工程实践总结
    2020软件工程第五次作业05
    软件工程问题清单
    2020软件工程第四次作业04
    用SQL*Plus命令启动和关闭数据库
    2020软件工程第三次作业03
    2020软件工程作业02
    图像处理问题清单
    2020软件工程作业01
    Markdown 快速入门
  • 原文地址:https://www.cnblogs.com/xiangnan6122/p/10202910.html
Copyright © 2020-2023  润新知