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

类结构



NioEventLoopGroup继承自MultithreadEventLoopGroup,多提供了两个方法setIoRatiorebuildSelectors,一个用于设置NioEventLoop用于IO处理的时间占比,另一个是重新构建Selectors,来处理epoll空轮询导致CPU100%的bug。这个两个的用处在介绍NioEventLoop的时候在详细介绍。其它的方法都在接口中有定义,先看下EventExecutorGroup

EventExecutorGroup

EventExecutorGroup继承自ScheduledExecutorServiceIterable。这意味着EventExecutorGroup拥有定时处理任务的能力,同时本身可以迭代。它提供的方法有:

    /**
* 是否所有事件执行器都处在关闭途中或关闭完成
*/
boolean isShuttingDown(); /**
* 优雅关闭
*/
Future<?> shutdownGracefully(); Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit); /**
* 返回线程池终止时的异步结果
*/
Future<?> terminationFuture(); void shutdown(); List<Runnable> shutdownNow(); /**
* 返回一个事件执行器
*/
EventExecutor next();

其中shutdownshutdownNow被标记为过时,不建议使用。EventExecutorGroup还重写ScheduledExecutorService接口的方法,用于返回自定义的Future

EventLoopGroup

EventLoopGroup继承自EventExecutorGroup,它和EventExecutorGroup想比多了注册ChannelChannelPromise,同时重新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的创建,包括创建的异常处理,成功通知等。

AbstractEventExecutorGroupMultithreadEventLoopGroupNioEventLoopGroup内部没有特殊之处,就不拓展了。

文中帖的代码注释全在:KAMIJYOUDOUMA, 有兴趣的童鞋可以关注一下。


本篇到此结束,如果读完觉得有收获的话,欢迎点赞、关注、加公众号【贰级天災】,查阅更多精彩历史!!!

Netty源码分析(四):EventLoopGroup的更多相关文章

  1. [编织消息框架][netty源码分析]5 EventLoopGroup 实现类NioEventLoopGroup职责与实现

    分析NioEventLoopGroup最主有两个疑问 1.next work如何分配NioEventLoop 2.boss group 与child group 是如何协作运行的 从EventLoop ...

  2. Netty源码分析第1章(Netty启动流程)---->第1节: 服务端初始化

    Netty源码分析第一章:  Server启动流程 概述: 本章主要讲解server启动的关键步骤, 读者只需要了解server启动的大概逻辑, 知道关键的步骤在哪个类执行即可, 并不需要了解每一步的 ...

  3. Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用

    Netty源码分析第一章:Netty启动流程   第四节:注册多路复用 回顾下以上的小节, 我们知道了channel的的创建和初始化过程, 那么channel是如何注册到selector中的呢?我们继 ...

  4. Netty源码分析第4章(pipeline)---->第7节: 前章节内容回顾

    Netty源码分析第四章: pipeline 第七节: 前章节内容回顾 我们在第一章和第三章中, 遗留了很多有关事件传输的相关逻辑, 这里带大家一一回顾 首先看两个问题: 1.在客户端接入的时候, N ...

  5. netty源码分析(十八)Netty底层架构系统总结与应用实践

    一个EventLoopGroup当中会包含一个或多个EventLoop. 一个EventLoop在它的整个生命周期当中都只会与唯一一个Thread进行绑定. 所有由EventLoop所处理的各种I/O ...

  6. Netty源码分析(前言, 概述及目录)

    Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...

  7. 【转】netty源码分析之LengthFieldBasedFrameDecoder

    原文:https://www.jianshu.com/p/a0a51fd79f62 拆包的原理 关于拆包原理的上一篇博文 netty源码分析之拆包器的奥秘 中已详细阐述,这里简单总结下:netty的拆 ...

  8. Netty源码分析第1章(Netty启动流程)---->第2节: NioServerSocketChannel的创建

    Netty源码分析第一章:  Server启动流程 第二节:NioServerSocketChannel的创建 我们如果熟悉Nio, 则对channel的概念则不会陌生, channel在相当于一个通 ...

  9. Netty源码分析第1章(Netty启动流程)---->第3节: 服务端channel初始化

    Netty源码分析第一章:Netty启动流程   第三节:服务端channel初始化 回顾上一小节的initAndRegister()方法: final ChannelFuture initAndRe ...

  10. Netty源码分析第2章(NioEventLoop)---->第1节: NioEventLoopGroup之创建线程执行器

    Netty源码分析第二章: NioEventLoop 概述: 通过上一章的学习, 我们了解了Server启动的大致流程, 有很多组件与模块并没有细讲, 从这个章开始, 我们开始详细剖析netty的各个 ...

随机推荐

  1. DWM1000 定位操作流程--[蓝点无限]

    蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 1烧录HEX文件 使用ST-LINK utility 烧录HEX文件,分别烧录三个基站以及一个标签,烧录基站时 ...

  2. company_base_info_staff_job

    "company_base_info_staff_job": { "engine": "python script", # datax or ...

  3. browser-sync + http-proxy-middleware 配置代理跨域

    写代理js文件下面是文件内容 /** * Module dependencies. */ var browserSync = require('browser-sync').create() var ...

  4. Java 跨平台原理

    Java的跨平台基于编译器和虚拟机.其中,CPU处理器和操作系统的整体称为平台.编译器把源文件编译成与平台无关的基于Unicode的字节码class文件,虚拟机把该文件解释成与平台有关的机器码指令,可 ...

  5. ef.core Mysql

    Entity层 using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; ...

  6. openCV 简单实现身高测量(未考虑相机标定,windows)

    (一) OpenCV3.1.0+VS2015开发环境配置 下载OpenCV安装包(笔者下载3.1.0版本) 环境变量配置(opencv安装路径\build\x64\vc14\bin,注意的是x64文件 ...

  7. hadoop伪分布式搭建

    安装好jdk 减压hadoop压缩包 cd /home/hadoop/hadoop-2.7.3/etc/hadoop vi hadoop-env.sh 文件末尾处添加 jdk环境变量 export J ...

  8. framework7 入门(基础布局)

    个人认为framework7是个很好的移动端框架,自带路由.下拉刷新.无限加载.时间线.各种dialog.环形图等,基本能满足大部分app的需求,可以和vue,webpack 等各种搭配. 这里讲一下 ...

  9. 小程序wx:for循环列表数量的限制

    数据有100条,我们只要页面显示一部分,就要通过index来限制.index<3,就是显示序列0,1,2这三条数据.具体写法: <block wx:for='{{list}}' wx:ke ...

  10. 微信小程序60秒倒计时

    微信小程序发送短信验证码后60秒倒计时功能,效果图: 完整代码 index.wxml <!--index.wxml--> <view class="container&qu ...