向南是个万人迷

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

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之创建线程执行器

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

 

posted on 2018-12-31 18:43  向南是个万人迷  阅读(1004)  评论(0编辑  收藏  举报