简介

在netty中不管是服务器端的ServerBootstrap还是客户端的Bootstrap,在创建的时候都需要在group方法中传入一个EventLoopGroup参数,用来处理所有的ServerChannel和Channel中所有的IO操作和event。

可能有的小伙伴还稍微看了一下netty的源码,可能会发现还有一个和EventLoopGroup非常类似的类叫做EventLoop。那么EventLoopGroup和EventLoop有什么关系呢?他们的底层和channel的交互关系是怎么样的呢?一起来看看吧。

EventLoopGroup和EventLoop

EventLoopGroup继承自EventExecutorGroup:

public interface EventLoopGroup extends EventExecutorGroup

在前面的文章中我们讲过,EventExecutorGroup中有一个next方法可以返回对应的EventExecutor,这个方法在EventLoopGroup中进行了重写:

    EventLoop next();

next方法返回的不再是一个EventExecutor,而是一个EventLoop。

事实上,EventLoop和EventLoopGroup的关系与EventExecutor和EventExecutorGroup的关系有些类似,EventLoop也是继承自EventLoopGroup,EventLoopGroup是EventLoop的集合。

public interface EventLoop extends OrderedEventExecutor, EventLoopGroup

在EventLoopGroup中,除了重写的next方法之外,还添加了channel的注册方法register,用于将channel和注册到EventLoop中,从而实现channel和EventLoop的绑定。

ChannelFuture register(Channel channel);

在EventLoop中,自多添加了一个parent方法,用来表示EventLoop和EventLoopGroup的关联关系:

EventLoopGroup parent();

EventLoopGroup在netty中的默认实现

EventLoopGroup在netty中的默认实现叫做DefaultEventLoopGroup,先来看一下它的继承关系:

如果看了之前我讲解的关于EventExecutorGroup的朋友可以看出来,DefaultEventLoopGroup和DefaultEventExecutorGroup的继承关系是很类似的,DefaultEventLoopGroup继承自MultithreadEventLoopGroup,而MultithreadEventLoopGroup又继承自MultithreadEventExecutorGroup并且实现了EventLoopGroup接口:

public abstract class MultithreadEventLoopGroup extends MultithreadEventExecutorGroup implements EventLoopGroup

MultithreadEventLoopGroup是用多线程来处理Event Loop。

在MultithreadEventLoopGroup中定义了一个DEFAULT_EVENT_LOOP_THREADS来存储默认的处理Event Loop线程的个数:

DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
"io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));

对于EventLoopGroup中新加的几个register方法,MultithreadEventLoopGroup都是调用对应的next方法来实现的:

public ChannelFuture register(Channel channel) {
return next().register(channel);
}

这里的next()方法的实现实际上调用的是父类的next方法,也就是MultithreadEventExecutorGroup中的next方法,来选择Group管理的一个EventLoop:

public EventLoop next() {
return (EventLoop) super.next();
}

对于DefaultEventLoopGroup来说,它继承自MultithreadEventLoopGroup,实现了一个newChild方法,用来将传入的executor封装成为EventLoop:

    protected EventLoop newChild(Executor executor, Object... args) throws Exception {
return new DefaultEventLoop(this, executor);
}

EventLoop在netty中的默认实现

EventLoop在netty中的默认实现叫做DefaultEventLoop,先来看下它的继承关系:

DefaultEventLoop继承自SingleThreadEventLoop,而SingleThreadEventLoop又继承自SingleThreadEventExecutor并且实现了EventLoop接口。

先来看下SingleThreadEventLoop的实现:

public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor implements EventLoop

SingleThreadEventLoop使用单一线程来执行提交的任务。它和SingleThreadEventExecutor相比有什么变化呢?

首先 提供了一个tailTasks用来存储pending的tasks:

private final Queue<Runnable> tailTasks;

这个tailTasks会被用在任务个数的判断和操作上:

    final boolean removeAfterEventLoopIterationTask(Runnable task) {
return tailTasks.remove(ObjectUtil.checkNotNull(task, "task"));
} protected boolean hasTasks() {
return super.hasTasks() || !tailTasks.isEmpty();
} public int pendingTasks() {
return super.pendingTasks() + tailTasks.size();
}

SingleThreadEventLoop中对register方法的实现最终调用的是注册的channel中unsafe的register方法:

channel.unsafe().register(this, promise);

再来看一下DefaultEventLoop,DefaultEventLoop继承自SingleThreadEventLoop:

public class DefaultEventLoop extends SingleThreadEventLoop

除了构造函数之外,DefaultEventLoop实现了一个run方法,用来具体任务的执行逻辑:

    protected void run() {
for (;;) {
Runnable task = takeTask();
if (task != null) {
task.run();
updateLastExecutionTime();
} if (confirmShutdown()) {
break;
}
}
}

如果对比可以发现,DefaultEventLoop和DefaultEventExecutor中run方法的实现是一样的。

总结

本文介绍了netty中EventLoop和EventLoopGroup的默认实现:DefaultEventLoop和DefaultEventLoopGroup,但是不知道小伙伴们有没有发现,即使在最简单的netty应用中也很少看到这两个默认的EventLoop。最常用的反而是NioEventLoopGroup和NioEventLoop,这是因为DefaultEventLoop和DefaultEventLoopGroup只是使用了多线程技术,一个线程代表一个EventLoop,在EventLoop过多的情况下可能会造成线程和性能的浪费,所以在NioEventLoopGroup和NioEventLoop使用了NIO技术,通过使用channel、selector等NIO技术提升了EventLoop的效率。关于NioEventLoopGroup和NioEventLoop的详细介绍,我们会在后一章中详细讲解,敬请期待。

本文已收录于 http://www.flydean.com/05-1-netty-eventloop-eventloopgroup/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

netty系列之:EventLoop,EventLoopGroup和netty的默认实现的更多相关文章

  1. netty系列之:Bootstrap,ServerBootstrap和netty中的实现

    目录 简介 Bootstrap和ServerBootstrap的联系 AbstractBootstrap Bootstrap和ServerBootstrap 总结 简介 虽然netty很强大,但是使用 ...

  2. netty系列之:EventExecutor,EventExecutorGroup和netty中的实现

    目录 简介 EventExecutorGroup EventExecutor EventExecutorGroup在netty中的基本实现 EventExecutor在netty中的基本实现 总结 简 ...

  3. netty系列之:channel,ServerChannel和netty中的实现

    目录 简介 channel和ServerChannel netty中channel的实现 AbstractChannel和AbstractServerChannel LocalChannel和Loca ...

  4. Netty系列之Netty线程模型

    Reference: http://www.infoq.com/cn/articles/netty-threading-model 1. 背景 1.1. Java线程模型的演进 1.1.1. 单线程 ...

  5. netty系列之:netty初探

    目录 简介 netty介绍 netty的第一个服务器 netty的第一个客户端 运行服务器和客户端 总结 简介 我们常用浏览器来访问web页面得到相关的信息,通常来说使用的都是HTTP或者HTTPS协 ...

  6. netty系列之:中国加油

    目录 简介 场景规划 启动Server 启动客户端 消息处理 消息处理中的陷阱 总结 简介 之前的系列文章中我们学到了netty的基本结构和工作原理,各位小伙伴一定按捺不住心中的喜悦,想要开始手写代码 ...

  7. Netty 系列一(核心组件和实例).

    一.概念 早期的 Java API 只支持由本地系统套接字库提供所谓的阻塞函数来支持网络编程.由于是阻塞 I/O ,要管理多个并发客户端,需要为每个新的客户端Socket 创建一个 Thread .这 ...

  8. Netty 系列(三)Netty 入门

    Netty 系列(三)Netty 入门 Netty 是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更多请参考:Netty Github 和 Netty中文 ...

  9. 【读后感】Netty 系列之 Netty 高性能之道 - 相比 Mina 怎样 ?

    [读后感]Netty 系列之 Netty 高性能之道 - 相比 Mina 怎样 ? 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商 ...

随机推荐

  1. Java语法专题1: 类的构造顺序

    合集目录 Java语法专题1: 类的构造顺序 问题 下面的第二个问题来源于Oracle的笔试题, 非常经典的一个问题, 我从07年开始用了十几年. 看似简单, 做对的比例不到2/10. 描述一下多级继 ...

  2. 图论+回溯解QQ一笔画红包

    [春节整活] QQ的一笔画红包有几个特性: 1.最大为5×5的点阵,所以可以把每个点从左到右,从上到下标为1-25号点 2.每两个点只能存在一条线 3.线可以被盖住(例如连接2-1-3,2-1的线会被 ...

  3. 马哈鱼间接数据流中的where-group-by子句

    马哈鱼间接数据流中的where-group-by子句 本文介绍间接数据流中的where-group-by子句. 1.列在where子句中 WHERE子句中源表中的某些列不影响目标列,但对所选行集至关重 ...

  4. SSL证书,IIS7、IIS8,http自动跳转到HTTPS

    安装"URL REWRITE2 " 伪静态模块,IIS7需要先确认是否安装 "URL REWRITE2 " 伪静态模块 , 如果您已经安装可以跳过 下载地址:h ...

  5. 连接mysql出现“Unable to load authentication plugin 'caching_sha2_password”错误

    这是mysql 8.0版本才出现的问题,原因是mysql 8.0 默认使用 caching_sha2_password 身份验证机制 -- 从原来的 mysql_native_password 更改为 ...

  6. bom-删除提示

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Typora快捷键 shortcuts-windows

    Typora快捷键 shortcuts-windows 快捷键 作用 ctrl+ ctrl- 字体大小调节 ctrl + shift + ` 行内代码 alt+shift+5 删除线 ctrl+shi ...

  8. LAMP架构—源码编译安装 (爱情受过伤,为爱跳过鸭绿江)

    LAMP架构--源码编译安装 1.LAMP架构概述 2.编译安装Apache httpd 服务 3.编译安装mysql 服务 4.编译安装PHP 解析服务 5.利用LAMP搭建论坛 1.LAMP架构概 ...

  9. 4G无线全网通太阳能水文设备电源监测系统BMS110

    钡铼技术BMS110模块可实现4路电池电压.2路模拟量.2路数字量和1路温度测量,支持Modbus RTU over TCP和MQTT通讯协议,DC9-36V电源供电.BMS110可应用于各种有使用蓄 ...

  10. 从服务间的一次调用分析整个springcloud的调用过程(一)

    首先我们知道springcloud是一个微服务框架,按照官方文档的说法,springcloud提供了一些开箱即用的功能: 1 分布式/版本化配置 2 服务的注册与发现 3 路由 4 服务到服务之间调用 ...