在线客服
扫描二维码
下载博学谷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线程异步通知业务的方式,所以在整个请求 -> 响应过程中业务线程不会由于阻塞等待而不能干其他事情。
— 申请免费试学名额 —
在职想转行提升,担心学不会?根据个人情况规划学习路线,闯关式自适应学习模式保证学习效果
讲师一对一辅导,在线答疑解惑,指导就业!
相关推荐 更多
MySQL中数据库的设计归纳讲解
谈到MySQL中数据库的设计,相信大家都知道这是实现实际业务的重要一步,因此对于Java学习者来说,深入了解和学习数据库的设计是十分有必要的。本文为大家准备了一份MySQL中数据库的设计归纳讲解,内容包括了多表之间的关系,像是分类、实现以及案例分析,还有数据库设计的范式概念和分类等等。有学习兴趣的朋友现在赶紧接着看下去吧!
4730
2020-02-13 14:53:59
Java对象内存分配过程如何保证线程安全?
Java一门面向对象的语言,在Java中使用的对象都需要被创建出来,在Java中创建一个对象的方法有很多种,但对象在创建过程中都需要进行内存分配。Java对象内存分配过程保证线程安全,对象的内存分配过程就必须进行同步控制。
5897
2020-03-17 15:08:17
Java学习的重点难点是什么?新手入门有哪些门槛?
对于新入行的同学而言,开始学习Java是一个非常关键的过程,很多同学因为不了解Java学习的重点难点知识,导致学习中遇到诸多的问题,甚至走了不少弯路。那Java学习中的重点难点是什么?新手入门有哪些门槛呢?
7230
2020-07-29 09:40:55
Java开发中的I/O模型原理解析
Java开发中的I/O模型原理解析,I/O是 input/output的缩写即输入输出端口。每个设备都会有一个专用的I/O地址用来处理自己的输入输出信息。常见的五种IO模型分别是:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。
4302
2021-05-13 09:59:24
Spring框架实现依赖注入操作步骤解析
Dependency Injection是spring框架核心 ioc 的具体实现。程序在编写时通过控制反转把对象的创建交给了spring,但是代码中不可能出现没有依赖的情况。ioc 解耦只是降低他们的依赖关系但不会消除,坐等框架把持久层对象传入业务层而不用我们自己去获取。
5187
2021-05-24 11:31:52
