常规的线程逻辑是用Runnable
或者Thread
创建线程,然后调用start()
。这个做法的缺点是,线程的行为和线程的创建绑定到了一起。
所以最好是将线程的创建与它的任务解耦。
命令模式
ThreadFactory DefaultThreadFactory Excutor SerialExecutor
首先给出其类层次图
跟踪NioEventLoopGroup的默认构造方法,直至MultithreadEventExecutorGroup的构造方法:
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args) {
// NioEventLoopGroup是一个MultithreadEventExecutorGroup
// 也就是基于多线程的Nio事件循环
if (nThreads <= 0) {
throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
}
if (executor == null) {
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
// 它的Executor是会为每一个任务创建一个新线程。
}
children = new EventExecutor[nThreads];
for (int i = 0; i < nThreads; i ++) {
boolean success = false;
try {
children[i] = newChild(executor, args);
// 在NioEventLoopGroup中,chlidren的每个元素其实都是一个NioEventLoop
success = true;
}
...
其中children的类型为EventExcutor[]
。
其内部维护了一个EventExcutor数组,每个元素都由newChild
构造,而该方法在NioEventLoopGroup.newChild
有实现:
@Override
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
数组,名叫children。