1.NioEventLoopGroup的继承体系图
可以看到EventExecutorGroup是继承自ScheduleExecutorService 和 Iterable
这就意味着存在线程池和迭代器,那么NioEventLoopGroup是对线程池做了什么,迭代器又在迭代什么?往下瞅瞅~
2. EventExecutorGroup 核心接口功能描述
EventExecutorGroup作为核心接口,定义了基本的核心功能。那么它是干啥的呢?
官方解释:
EventExecutorGroup负责通过自己的next()方法对外提供EventExecutor。而且它也负责处理这些EventExecutor的生命周期,并对外提供全局关闭接口
从下面的方法中可以看到,EventExecutorGroup本身是具备线程池的功能的,然后内部还维护者一个EventExecutor的集合。
EventExecutor本身又是继承自EventExecutorGroup的
那么可想而知,EventExecutorGroup 就是一个线程池套一组线程池的线程池组管理工具
方法:
/**
* 检查所有被EventExecutorGroup管理的EventExecutor是否已经优雅的关闭了。
* 全部关闭才是true
*/
boolean isShuttingDown();
/**
* 基于默认值的 {shutdownGracefully(long, long, TimeUnit)}方法的简单调用方式
*/
Future<?> shutdownGracefully();
/**
*告知executor需要进行关闭,一旦这个方法调用了,那么isShuttingDown() 方法开始返回true,而executor也准备开始关闭自己。
* 不像shutdown()方法,这个会更优雅一点。它会有个关闭的静默期,如果在这期间有任务被提交,那么静默期就会重新计算。
* 总的来说就是:
* 在进行关闭前会等待一定时间,如果在这个期间有任务被提交,那么等待时间将重新开始计算
*/
Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit);
/**
* 所有被当前EventExecutorGroup管理的EventExecutor都进行关闭后会进行异步回调
*/
Future<?> terminationFuture();
/**
* 这个是强行关闭,已经不建议使用了
*/
@Override
@Deprecated
void shutdown();
/**
* 这个是强行关闭,已经不建议使用了
*
*/
@Override
@Deprecated
List<Runnable> shutdownNow();
/**
* (重要方法)
*返回EventExecutorGroup管理的诸多EventExecutor中的一个,这个由子类自己决定选择方式
*/
EventExecutor next();
/**
* =================================================
* 下面都是ScheduledExecutorService, Iterable<EventExecutor>的方法的重写(嗯,寂寞重写)
* =================================================
*/
@Override
Iterator<EventExecutor> iterator();
@Override
Future<?> submit(Runnable task);
@Override
<T> Future<T> submit(Runnable task, T result);
@Override
<T> Future<T> submit(Callable<T> task);
@Override
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
@Override
<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);
@Override
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
@Override
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
3.NioEventLoopGroup的初始化
它这个初始化,弯拐的比较多。其中涉及到几个默认参数值得思考。
它这里经过多层构造方法调用,然后进入父类构造MultithreadEventLoopGroup中,在这里再次进行多次构造方法调用。
这里涉及到几个构造组件:
Executor : new ThreadPerTaskExecutor(newDefaultThreadFactory())
SelectorProvider: 默认为SelectorProvider.provider()
Selector.select()轮询处理策略:DefaultSelectStrategyFactory.INSTANCE
线程池队列已满策略:RejectedExecutionHandlers.reject()
EventExecutor选择器:DefaultEventExecutorChooserFactory.INSTANCE
3.1那么NioEventLoopGroup默认的线程数是多少呢?
io.netty.channel.MultithreadEventLoopGroup
private static final int DEFAULT_EVENT_LOOP_THREADS;
static {
// 默认为cpu处理器核数*2
DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
"io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
if (logger.isDebugEnabled()) {
logger.debug("-Dio.netty.eventLoopThreads: {}", DEFAULT_EVENT_LOOP_THREADS);
}
}
3.2 核心初始化
下面这段代码主要干了两件事:
初始化自己的EventExecutor线程池集合(EventExecutor[] children
)
初始化了NioEventLoopGroup对EventExecutor集合的选择器(EventExecutorChooserFactory.EventExecutorChooser
)
对了,还构建了一个只读集合,暂时不知道干啥用,还有看到再补充
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args) {
// 检查nThreads是不是正数,默认是cpu核心数*2
checkPositive(nThreads, "nThreads");
// 如果自己不需要定制化线程池的,有默认的单线程线程池
if (executor == null) {
// 线程池初始化,没有任务队列
// newDefaultThreadFactory 负责线程的创建
// FastThreadLocalThread
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}
// 创建线程池组
children = new EventExecutor[nThreads];
for (int i = 0; i < nThreads; i ++) {
boolean success = false;
try {
// 创建 NioEventLoop作为线程池组管理的元素
children[i] = newChild(executor, args);
success = true;
} catch (Exception e) {
// TODO: Think about if this is a good exception type EventExecutorInitializeException 如何?
throw new IllegalStateException("failed to create a child event loop", e);
} finally {
if (!success) {
for (int j = 0; j < i; j ++) {
// 这里 j<i 很灵性,只需要关闭异常前创建的NioEventLoop
children[j].shutdownGracefully();
}
for (int j = 0; j < i; j ++) {
EventExecutor e = children[j];
try {
while (!e.isTerminated()) {
// 等待关闭
e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
}
} catch (InterruptedException interrupted) {
// Let the caller handle the interruption.
Thread.currentThread().interrupt();
break;
}
}
}
}
}
// EventExecutor 选择器,就是有请求来了,NioEventLoopGroup如何去选择EventExecutor去执行请求
chooser = chooserFactory.newChooser(children);
// 终止监听器,监听EventExecutor是否停掉
final FutureListener<Object> terminationListener = new FutureListener<Object>() {
@Override
public void operationComplete(Future<Object> future) throws Exception {
if (terminatedChildren.incrementAndGet() == children.length) {
terminationFuture.setSuccess(null);
}
}
};
for (EventExecutor e: children) {
e.terminationFuture().addListener(terminationListener);
}
Set<EventExecutor> childrenSet = new LinkedHashSet<EventExecutor>(children.length);
Collections.addAll(childrenSet, children);
// 只读EventExecutor集合
readonlyChildren = Collections.unmodifiableSet(childrenSet);
}
4.小结
从NioEventLoopGroup的初始化可以看到,其实它就是用来管理一系列的EventExecutor的。
下图是NioEventLoopGroup的基本组件结构