Netty学习:EventLoop事件机制
EventLoop是什么
如果你去百度EventLoop,肯定会百度到很多关于JavaScript,NodeJS的文章,是的,这两种语言的事件机制就依赖于EventLoop,但是EventLoop到底是什么,可以先思考2个问题:
- 一般情况下,当我们要实现令一个线程不断处理任务,都是选择使用while(true){……}这样的结构,但是往往为了防止无限循环空跑占用CPU时间,会在死循环中使用sleep()来空出时间。有更好的方法吗?
- Redis的性能毋庸置疑,但是Redis是单线程的,单线程的Redis是如何达到不逊色于多线程的性能的呢?(当然也是EventLoop)。
EventLoop事实上是一种线程编程模型,简而言之,将需要执行的任务封装成原子化的Event,都交到一个线程去执行,而这个线程唯一的任务就是不断的从自己的Event事件池中取出来Event去执行。那么为什么叫Loop呢?因为这种模型适用于非阻塞的操作,在非阻塞Event发生后,将该Event以及回调函数封装成一个CheckEvent,继续扔到Event池中,在不断执行Event的过程中,当执行到CheckEvent时,会去检查非阻塞操作是否成功,成功则执行回调,未成功则继续扔进去等待下一次,所以这种模型叫做EventLoop=事件轮询。
EventLoop适用的场景
或许你会说,EventLoop性能这么高,这么帅,那大家都用不就好了?事实上,EventLoop也有他局限的场景,如上所说,这种编程场景多用于该系统大多数事件可以封装成异步事件时,EventLoop会有更好的吞吐和执行效率,比如JavaScript要在js执行完后交由浏览器进行绘制这种图形客户端场景,或者redis这种使用密集IO型,或者Netty这种天生NIO框架。简而言之:异步非阻塞操作多,回调机制多。当你需要Check的事件不多,都是实际需要执行的任务时,EventLoop比起线程池,优势就微乎其微了,并且EventLoop的实现还更为复杂。所以不是什么场景都适合使用的。
Netty中的EventLoop
Netty中使用的当然也是EventLoop,这是它的一个优点或者说提升它性能的原因。
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(group)
Netty代码肯定少不了这几句,其中NioEventLoopGroup就是Netty的EventLoop实现,一个Group中包含多个EventLoop,类似线程池和线程的关系。支持构造函数传进去里面的线程数,如果不传的话默认是CPU数*2。
Netty中的大量inEventLoop判断
看过Netty源码的很多人肯定会看到Netty的源码中有大量的如下判断:
if (!inEventLoop && !executor.inEventLoop(currentThread)) {
executor.execute(new Runnable() {
});
}
这个判断是为什么呢?我一开始也很疑惑,后面随着对Netty的理解,才知道,对Netty来说,Netty许多函数的调用方,它并不知道调用方是谁,是在自己的内部EventLoop内,还是在用户线程里,所以它在一些用户很可能在用户线程里调用的方法,增加了这类判断,将这些方法的执行转移到EventLoop中。
Netty是如何建立连接并监听端口的-NIOSocketChannel
初看Netty源码,Netty是怎么建立端口监听以及连接的,都找了我许久。先上一段标准代码,这是netty源码例子中的代码。
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
final EchoServerHandler serverHandler = new EchoServerHandler();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
//p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(serverHandler);
}
});
// Start the server.
ChannelFuture f = b.bind(PORT).sync();
// Wait until the server socket is closed.
f.channel().closeFuture().sync();
} finally {
// Shut down all event loops to terminate all threads.
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
可以看到其中主要就是配置了EventLoopGroup,channel,handler,这三个东西,这三个东西就是netty三大件,总领了Netty。建立连接的就是其中的NioServerSocketChannel,这个NioSocketChannel这种是Netty包装了Java原生的SocketChannel,在启动时(server)或者进行请求时(client)通过反射进行创建并运行。
Netty,bossGroup与workerGroup
Netty默认构造函数,支持设置2个EventLoopGroup,其中分为Boss和Worker,其中Boss只负责处理连接请求的建立,以及key的select,类似主线程,Worker负责具体的读写,handler处理等其他任务,官方建议这两个的线程数比是1:5,实际使用中可以看情况设置。
Netty学习:EventLoop事件机制的更多相关文章
- Netty学习篇④-心跳机制及断线重连
心跳检测 前言 客户端和服务端的连接属于socket连接,也属于长连接,往往会存在客户端在连接了服务端之后就没有任何操作了,但还是占用了一个连接:当越来越多类似的客户端出现就会浪费很多连接,netty ...
- Netty学习摘记 —— 心跳机制 / 基于分隔符和长度的协议
本文参考 本篇文章是对<Netty In Action>一书第十一章"预置的ChannelHandler和编解码器"的学习摘记,主要内容为通过 SSL/TLS 保护 N ...
- 系统学习DOM事件机制
本文将从以下几个方面介绍DOM事件: 基本概念:DOM事件的级别 DOM事件模型,事件流 描述DOM事件捕获的具体流程 Event对象的常见应用 自定义事件 DOM事件的级别 //DOM0 eleme ...
- 【iScroll源码学习03】iScroll事件机制与滚动条的实现
前言 想不到又到周末了,周末的时间要抓紧学习才行,前几天我们学习了iScroll几点基础知识: 1. [iScroll源码学习02]分解iScroll三个核心事件点 2. [iScroll源码学习01 ...
- Netty 源码学习——EventLoop
Netty 源码学习--EventLoop 在前面 Netty 源码学习--客户端流程分析中我们已经知道了一个 EventLoop 大概的流程,这一章我们来详细的看一看. NioEventLoopGr ...
- Netty学习摘记 —— 再谈EventLoop 和线程模型
本文参考 本篇文章是对<Netty In Action>一书第七章"EventLoop和线程模型"的学习摘记,主要内容为线程模型的概述.事件循环的概念和实现.任务调度和 ...
- Ext JS学习第十七天 事件机制event(二)
此文仅有继续学习笔记: 昨天说了三种邦定事件的方法,今天说一下自定义事件 假设现在又这样的情景一个自定义的事件 没有用到事件处理的场景 母亲问孩子和不饿-> ...
- Netty学习(八)-Netty的心跳机制
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a953713428/article/details/69378412我们知道在TCP长连接或者Web ...
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
随机推荐
- GET和POST的区别与联系
每日知识-GET和POST HTTP:超文本传输协议 组成部分:请求行,请求头部,一个空行,请求数据 GET和POST GET:get就是获取的意思,默认的HTTP请求方式,把参数通过 key/val ...
- Hbase备份以及清表脚本
脚本主要是方便自己工作使用,服务器环境中配置了hbase相关环境变量 1.hbase备份脚本 #!/bin/bash tableList=("table1" "table ...
- WIN7环境下配置vscode c++环境
目录 安装vscode 添加中文环境支持 添加c++支持 配置c++环境 安装MinGW 配置MinGW环境变量 配置vscode launch文件配置 task文件配置 可能出现的问题 安装vsco ...
- 多任务-python实现-协程(2.1.11)
多任务-python实现-协程(2.1.11) 23/100 发布文章 qq_26624329 @ 目录 1.概念 2.迭代器 1.概念 协程与子例程一样,协程(coroutine)也是一种程序组件. ...
- 30道 有趣的 的 JVM 面试题
目录 1.JVN内存结构 2.对象分配规则 3.解释内存中的栈(stack).堆(heap)和静态区(static area)的用法 4.Perm Space中保存什么数据?会引起OutOfMemor ...
- 它听键盘声就知道你敲的是什么——GitHub 热点速览 Vol.51
作者:HelloGitHub-小鱼干 本以为本周的 GitHub 和十二月一样平平无奇就那么度过了,结果 BackgroundMattingV2 重新刷新了本人的认知,还能这种骚操作在线实时抠视频去背 ...
- Python机器学习课程:线性回归算法
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 最基本的机器学习算法必须是具有单个变量的线性回归算法.如今,可用的高级机器学习算法,库和技术如此之多 ...
- js 根据条件删除数组中某个对象&js filter (find)过滤数组对象的使用
删除 ---- item不设置 arr.splice(1,1) //['a','c','d'] 删除起始下标为1,长度为1的一个值,len设置的1,如果为0,则数组不变 arr. ...
- [每日一题]ES6中为什么要使用Symbol?
关注「松宝写代码」,精选好文,每日面试题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目 ...
- 7. JDK拍了拍你:字符串拼接一定记得用MessageFormat#format
目录 ✍前言 版本约定 ✍正文 DateFormat:日期时间格式化 SimpleDateFormat NumberFormat:数字格式化 DecimalFormat 一.0和#的使用(最常见使用场 ...