在线客服
扫描二维码
下载博学谷APP扫描二维码
关注博学谷微信公众号
Java开发中Netty线程模型原理解析,Netty是Java领域有名的开源网络库具有高性能和高扩展性的特点,很多流行的框架都是基于它来构建。Netty 线程模型不是一成不变的,取决于用户的启动参数配置。通过设置不同的启动参数Netty ,可同时支持 Reactor 单线程模型、多线程模型。
Netty线程模型就是Reactor模式的实现,如图:
一、线程组
Netty抽象了两组线程池BossGroup和WorkerGroup,其类型都是NioEventLoopGroup,BossGroup用来接受客户端发来的连接WorkerGroup则负责对完成TCP三次握手的连接进行处理。
NioEventLoopGroup里面包含了多个NioEventLoop管理NioEventLoop的生命周期。每个NioEventLoop中包含了一个NIO Selector、一个队列、一个线程;其中线程用来做轮询注册到Selector上的Channel的读写事件和对投递到队列里面的事件进行处理。
Boss NioEventLoop线程的执行步骤:
(1)处理accept事件与client建立连接, 生成NioSocketChannel。
(2)将NioSocketChannel注册到某个worker NIOEventLoop上的selector
(3)处理任务队列的任务 即runAllTasks。
Worker NioEventLoop线程的执行步骤:
(1)轮询注册到自己Selector上的所有NioSocketChannel的read和write事件。
(2)2处理read和write事件在对应NioSocketChannel处理业务。
(3)#runAllTasks处理任务队列TaskQueue的任务,一些耗时的业务处理可以放入TaskQueue中慢慢处理这样不影响数据在pipeline中的流动处理。
Worker NIOEventLoop处理NioSocketChannel业务时,使用了pipeline (管道),管道中维护了handler处理器链表用来处理channel中的数据。
二、ChannelPipeline
Netty将Channel的数据管道抽象为ChannelPipeline,消息在ChannelPipline中流动和传递。ChannelPipeline持有I/O事件拦截器ChannelHandler的双向链表,由ChannelHandler对I/O事件进行拦截和处理,可以方便的新增和删除ChannelHandler来实现不同的业务逻辑定制不需要对已有的ChannelHandler进行修改能够实现对修改封闭和对扩展的支持。
ChannelPipeline是一系列的ChannelHandler实例,流经一个Channel的入站和出站事件可以被ChannelPipeline 拦截。每当一个新的Channel被创建了,都会建立一个新的ChannelPipeline并绑定到该Channel上,这个关联是永久性的;Channel既不能附上另一个ChannelPipeline也不能分离当前这个。这些都由Netty负责完成,而无需开发人员的特别处理。
根据起源一个事件将由ChannelInboundHandler或ChannelOutboundHandler处理,ChannelHandlerContext实现转发或传播到下一个ChannelHandler。一个ChannelHandler处理程序可以通知ChannelPipeline中的下一个ChannelHandler执行。Read事件(入站事件)和write事件(出站事件)使用相同的pipeline,入站事件会从链表head 往后传递到最后一个入站的handler出站事件会从链表tail往前传递到最前一个出站的 handler,两种类型的 handler 互不干扰。
ChannelInboundHandler回调方法:
ChannelOutboundHandler回调方法:
三、异步非阻塞
写操作:通过NioSocketChannel的write方法向连接里面写入数据时候是非阻塞的,马上会返回即使调用写入的线程是我们的业务线程。Netty通过在ChannelPipeline中判断调用NioSocketChannel的write的调用线程是不是其对应的NioEventLoop中的线程,如果发现不是则会把写入请求封装为WriteTask投递到其对应的NioEventLoop中的队列里面,然后等其对应的NioEventLoop中的线程轮询读写事件时候,将其从队列里面取出来执行。
读操作:当从NioSocketChannel中读取数据时候并不是需要业务线程阻塞等待,而是等NioEventLoop中的IO轮询线程发现Selector上有数据就绪时,通过事件通知方式来通知业务数据已就绪,可以来读取并处理了。
每个NioSocketChannel对应的读写事件都是在其对应的NioEventLoop管理的单线程内执行,对同一个NioSocketChannel不存在并发读写,所以无需加锁处理。
使用Netty框架进行网络通信时,当我们发起I/O请求后会马上返回,而不会阻塞我们的业务调用线程;如果想要获取请求的响应结果,也不需要业务调用线程使用阻塞的方式来等待,而是当响应结果出来的时候,使用I/O线程异步通知业务的方式,所以在整个请求 -> 响应过程中业务线程不会由于阻塞等待而不能干其他事情。
— 申请免费试学名额 —
在职想转行提升,担心学不会?根据个人情况规划学习路线,闯关式自适应学习模式保证学习效果
讲师一对一辅导,在线答疑解惑,指导就业!
相关推荐 更多
Java基础学习之java序列化介绍
序列化是将对象的状态信息转换为可以储存或者传输的形式的过程。因此在Java开发中,序列化是一个非常重要的环节。Java序列化可以在JVM停止运行之后能够保存(持久化)制定的对象,并在将来重新读取被保存的对象。
6905
2019-06-25 18:26:59
自学Java可以找到工作吗?要学到什么程度?
Java作为备受程序员喜爱的编程语言,在各行各业都被广泛使用,导致当下越来越来多的自学者想通过自己的努力,自学Java从而找到一份高薪可以改变自己职业前途的工作。那么自学Java可以找到工作吗?要学到什么程度?其实对大多数学习者来说,自学Java都不是一个最好的选择,一方面是因为Java语言自身学习的难度比较高,另一方面是自学效率低,对自学者能力要求高。
6516
2019-10-26 11:33:24
Java基础语法之if语句学习笔记
众所周知,流程控制语句可以分为三类,分别是顺序结构、分支结构和循环结构,而分支结构又可以分为if语句和switch语句。顺序结构可以说是程序中最简单最基本的流程控制,这里就不展开详细讲解了。本文重点要讲解分析的是分支结构的if语句,内容包括了if语句的格式、执行流程和具体示例。想要学习Java基础语法的小伙伴,可以看看下面整理的if语句的笔记,希望对大家入门Java能够有所帮助。
7237
2019-12-06 12:40:32
Java基础语法之多线程学习笔记整理
众所周知,利用好多线程机制,可以大大提高系统整体的并发能力以及性能,而且线程间的切换和调度的成本小。因此,多线程是Java学习者必须掌握的语法重点。本文为大家整理了进程和线程、实现多线程方式、设置和获取线程名称、线程优先级和线程控制等等多线程知识点笔记,有需要的朋友一起来学习吧!
5781
2019-12-09 14:33:59
Nginx入门学习之应用场景
每当网站访问量较高的时候,网站的反应速度就变得非常缓慢,特别是图片、css、js等这些静态资源的加载,这个时候应该怎么办呢?其实只需一个Nginx就可以轻松解决上述问题,因为Nginx擅长处理像图片、css这样的静态资源。下面我们就开始入门学习Nginx的三大应用场景吧!
4664
2020-08-14 15:41:34