全网最通俗易懂的netty源码--EventLoopGroup的初始化
以EchoServer类为例,其通过下面这两行代码初始化了两个EventLoopGroup。
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
下面就来探究NioEventLoopGroup实例化背后的原理。查看其构造函数
NioEventLoopGroup
public NioEventLoopGroup() {
this(0);
}
调用同类中的另一个构造函数
public NioEventLoopGroup(int nThreads) {
this(nThreads, (Executor) null);
}
继续调用下去
public NioEventLoopGroup(int nThreads, Executor executor) {
this(nThreads, executor, SelectorProvider.provider());
}
public NioEventLoopGroup(
int nThreads, Executor executor, final SelectorProvider selectorProvider) {
this(nThreads, executor, selectorProvider, DefaultSelectStrategyFactory.INSTANCE);
}
public NioEventLoopGroup(int nThreads, Executor executor, final SelectorProvider selectorProvider,
final SelectStrategyFactory selectStrategyFactory) {
super(nThreads, executor, selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject());
}
到这里,调用父类的构造方法
MultithreadEventLoopGroup
protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
}
进一步调用到父类
MultithreadEventExecutorGroup
protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object... args) {
this(nThreads, executor, DefaultEventExecutorChooserFactory.INSTANCE, args);
}
最终干活的构造函数
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args) {
if (nThreads <= 0) {
throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
}
if (executor == null) {
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}
//构造线程数组
children = new EventExecutor[nThreads];
//下面这个for循环将实例化children数组中的每一个元素
for (int i = 0; i < nThreads; i ++) {
boolean success = false;
try {
//实例化!!!!!!(准确的说不是创建线程,而是NioEventLoop,只是该对象关联了线程)
children[i] = newChild(executor, args);
success = true;
} catch (Exception e) {
} finally {
}
}
}
这个函数比较复杂,我们先不看这么多。其中,跟本节主题相关的就下面两行代码
//构造线程数组
children = new EventExecutor[nThreads];
这行代码主要就是为EventLoopGroup构造底层最重要的数据结构,线程数组。
//实例化!!!!!!(准确的说不是创建线程,而是NioEventLoop,只是该对象关联了线程)
children[i] = newChild(executor, args);
这一步是在循环中往上面的children数组中构建NioEventLoop对象。这个构造过程也比较复杂,我们以后会分析,现在记住这个结论就好了。
还需要注意的是,在构造函数的一路调用中,有下面几个参数需要注意
nThreads、executor、chooserFactory、selectorProvider、selectStrategyFactory、rejectedExecutionHandler
这几个参数很重要,后面会着重分析。文章的风格就是这样,先把握大局,以免掉入到各种复杂的细节中去挣扎很久还不知讲的啥。然后宏观的理清楚之后再一个个去分析里面的细节。
EventLoopGroup的初始化过程就讲完了,简单吧。