EventLoop是什么

如果你去百度EventLoop,肯定会百度到很多关于JavaScript,NodeJS的文章,是的,这两种语言的事件机制就依赖于EventLoop,但是EventLoop到底是什么,可以先思考2个问题:

  1. 一般情况下,当我们要实现令一个线程不断处理任务,都是选择使用while(true){……}这样的结构,但是往往为了防止无限循环空跑占用CPU时间,会在死循环中使用sleep()来空出时间。有更好的方法吗?
  2. 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事件机制的更多相关文章

  1. Netty学习篇④-心跳机制及断线重连

    心跳检测 前言 客户端和服务端的连接属于socket连接,也属于长连接,往往会存在客户端在连接了服务端之后就没有任何操作了,但还是占用了一个连接:当越来越多类似的客户端出现就会浪费很多连接,netty ...

  2. Netty学习摘记 —— 心跳机制 / 基于分隔符和长度的协议

    本文参考 本篇文章是对<Netty In Action>一书第十一章"预置的ChannelHandler和编解码器"的学习摘记,主要内容为通过 SSL/TLS 保护 N ...

  3. 系统学习DOM事件机制

    本文将从以下几个方面介绍DOM事件: 基本概念:DOM事件的级别 DOM事件模型,事件流 描述DOM事件捕获的具体流程 Event对象的常见应用 自定义事件 DOM事件的级别 //DOM0 eleme ...

  4. 【iScroll源码学习03】iScroll事件机制与滚动条的实现

    前言 想不到又到周末了,周末的时间要抓紧学习才行,前几天我们学习了iScroll几点基础知识: 1. [iScroll源码学习02]分解iScroll三个核心事件点 2. [iScroll源码学习01 ...

  5. Netty 源码学习——EventLoop

    Netty 源码学习--EventLoop 在前面 Netty 源码学习--客户端流程分析中我们已经知道了一个 EventLoop 大概的流程,这一章我们来详细的看一看. NioEventLoopGr ...

  6. Netty学习摘记 —— 再谈EventLoop 和线程模型

    本文参考 本篇文章是对<Netty In Action>一书第七章"EventLoop和线程模型"的学习摘记,主要内容为线程模型的概述.事件循环的概念和实现.任务调度和 ...

  7. Ext JS学习第十七天 事件机制event(二)

    此文仅有继续学习笔记: 昨天说了三种邦定事件的方法,今天说一下自定义事件 假设现在又这样的情景一个自定义的事件 没有用到事件处理的场景        母亲问孩子和不饿->             ...

  8. Netty学习(八)-Netty的心跳机制

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a953713428/article/details/69378412我们知道在TCP长连接或者Web ...

  9. Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G

    code&monkey   Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...

随机推荐

  1. curl使用技巧汇总

    1,curl 忽略证书安全验证 curl https://192.168.1.5:8443-insecure -I

  2. Docker(五):Docker安装Elasticsearch

    查找ElasticSearch镜像 镜像仓库 https://hub.docker.com/ 下拉镜像 docker pull elasticsearch:7.7.0 查看镜像 docker imag ...

  3. gitbook 安装和使用

    gitbook 安装和使用 安装nodejs  wget https://nodejs.org/dist/v10.22.0/node-v10.22.0-linux-arm64.tar.xz tar - ...

  4. [日常摸鱼]UVA393 The Doors 简单计算几何+最短路

    The  Boy Next   Doors 题意:给定一个固定大小的房间($x,y$的范围都是$[0,10]$),有$n$个墙壁作为障碍(都与横坐标轴垂直),每个墙壁都有两扇门分别用四个点来描述,起点 ...

  5. Web服务器-服务器开发-返回浏览器需要的页面 (3.3.2)

    @ 目录 1.说明 2.代码 关于作者 1.说明 使用正则表达式,匹配客户端的请求头 获取到请求的路径 返回对应请求路径的文字 可以使用打开对应文件的方式去返回对应的文件 2.代码 from sock ...

  6. 正方形和球体,利用蒙特卡洛计算pi值

    clc; clear all; close all; R = 3; time = 10000; origin = [0,0,0]; %%======绘制球体====== t=linspace(0,pi ...

  7. Windows 安装 Go语言开发环境

    Windows 安装 Go语言开发环境   下载安装包 下载地址:http://www.golangtc.com/download   32 位请选择名称中包含 windows-386 的 msi 安 ...

  8. java实体类和json串字段名称不一致或者与map中字段名称不一致使用注解转化

    package yuanCheng; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List ...

  9. SpringBoot文件上传配置

    /** * 文件上传配置 * @return */ @Bean public MultipartConfigElement multipartConfigElement() { MultipartCo ...

  10. mysql组合索引之最左原则

    为什么在单列索引的基础上还需要组合索引? select product_id from orders where order_id in (123, 312, 223, 132, 224); 我们当然 ...