
无论服务端或客户端启动时都用到了
NioEventLoopGroup
,从名字就可以看出来它是NioEventLoop
的组合,是Netty多线程的基石。
类结构

NioEventLoopGroup
继承自
MultithreadEventLoopGroup
,多提供了两个方法
setIoRatio
和
rebuildSelectors
,一个用于设置
NioEventLoop
用于IO处理的时间占比,另一个是重新构建Selectors,来处理epoll空轮询导致CPU100%的bug。这个两个的用处在介绍
NioEventLoop
的时候在详细介绍。其它的方法都在接口中有定义,先看下
EventExecutorGroup
。
EventExecutorGroup
EventExecutorGroup
继承自ScheduledExecutorService
和Iterable
。这意味着EventExecutorGroup
拥有定时处理任务的能力,同时本身可以迭代。它提供的方法有:
/**
* 是否所有事件执行器都处在关闭途中或关闭完成
*/
boolean isShuttingDown();
/**
* 优雅关闭
*/
Future<?> shutdownGracefully();
Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit);
/**
* 返回线程池终止时的异步结果
*/
Future<?> terminationFuture();
void shutdown();
List<Runnable> shutdownNow();
/**
* 返回一个事件执行器
*/
EventExecutor next();复制
其中shutdown
和shutdownNow
被标记为过时,不建议使用。EventExecutorGroup
还重写ScheduledExecutorService
接口的方法,用于返回自定义的Future
。
EventLoopGroup
EventLoopGroup
继承自EventExecutorGroup
,它和EventExecutorGroup
想比多了注册Channel
和ChannelPromise
,同时重新next方法返回EventLoop
。
MultithreadEventExecutorGroup
创建NioEventLoopGroup
时,最终都会调用MultithreadEventExecutorGroup
的构造方法。
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args) {
// 线程数必须大于0
if (nThreads <= 0) {
throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
}
// 没指定Executor就创建新的Executor
if (executor == null) {
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}
// 创建EventExecutor数组
children = new EventExecutor[nThreads];
for (int i = 0; i < nThreads; i++) {
// 创建结果标识
boolean success = false;
try {
// 创建EventExecutor对象
children[i] = newChild(executor, args);
// 设置创建成功
success = true;
} catch (Exception e) {
throw new IllegalStateException("failed to create a child event loop", e);
} finally {
// 创建失败,关闭所有已创建的EventExecutor
if (!success) {
// 关闭所有已创建的EventExecutor
for (int j = 0; j < i; j++) {
children[j].shutdownGracefully();
}
// 确保所有已创建的EventExecutor已关闭
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选择器
chooser = chooserFactory.newChooser(children);
// 创建监听器,用于EventExecutor终止时的监听
final FutureListener<Object> terminationListener = new FutureListener<Object>() {
@Override
public void operationComplete(Future<Object> future) throws Exception {
// 当EventExecutor全部关闭时
if (terminatedChildren.incrementAndGet() == children.length) {
// 设置结果,并通知监听器们。
terminationFuture.setSuccess(null);
}
}
};
// 给每个EventExecutor添加上监听器
for (EventExecutor e : children) {
e.terminationFuture().addListener(terminationListener);
}
// 创建只读的EventExecutor集合
Set<EventExecutor> childrenSet = new LinkedHashSet<EventExecutor>(children.length);
Collections.addAll(childrenSet, children);
readonlyChildren = Collections.unmodifiableSet(childrenSet);
}复制
整个构造方法做的就是EventExecutor
的创建,包括创建的异常处理,成功通知等。AbstractEventExecutorGroup
、MultithreadEventLoopGroup
和NioEventLoopGroup
内部没有特殊之处,就不拓展了。
文中帖的代码注释全在:KAMIJYOUDOUMA, 有兴趣的童鞋可以关注一下。
本篇到此结束,如果读完觉得有收获的话,欢迎点赞、关注、加公众号【贰级天災】,查阅更多精彩历史!!!

文章转载自贰级天災,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
9.9 分高危漏洞,尽快升级到 pgAdmin 4 v9.2 进行修复
严少安
328次阅读
2025-04-11 10:43:23
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
318次阅读
2025-04-15 14:48:05
openHalo问世,全球首款基于PostgreSQL兼容MySQL协议的国产开源数据库
严少安
268次阅读
2025-04-07 12:14:29
postgresql+patroni+etcd高可用安装
necessary
145次阅读
2025-03-28 10:11:23
从 Oracle 到 PostgreSQL迁移成本评估揭秘
梧桐
139次阅读
2025-03-27 17:21:42
手把手教你在 openKylin 上部署 IvorySQL 4.4
严少安
139次阅读
2025-03-27 20:41:28
转发有奖 | PostgreSQL 16 PGCM高级认证课程直播班招生中!
墨天轮小教习
138次阅读
2025-04-14 15:58:34
墨天轮PostgreSQL认证证书快递已发(2025年3月批)
墨天轮小教习
116次阅读
2025-04-03 11:43:25
从Percona 发布Pro级产品得到的一些启发
库海无涯
115次阅读
2025-03-26 08:45:23
PostgreSQL消息队列拓展——PGQ
chirpyli
114次阅读
2025-03-25 09:09:09