在线客服
扫描二维码
下载博学谷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基础入门初学者归纳总结了数组的学习笔记,下面一起来看看吧~
3940
2020-05-25 15:33:04
Redis安装与部署新手入门教程
对于绝大多数初学者来说,安装Redis都是一个难关。这篇文章主要是分享一下如何在Linux中安装Redis服务。那么下面一起看看Redis安装与部署新手入门教程吧~
4721
2020-07-16 16:03:00
Java初学者须知编码规范
现代软件行业的高速发展对开发者的综合素质要求越来越高, 因为不仅是编程知识点,其它维度的知识点也会影响到软件的最终交付质量。比如: 数据库的表结构和索引设计缺陷可能带来软件上的架构缺陷或性能风险; 工程结构混乱导致后续维护艰难;没有鉴权的漏洞代码易被黑客攻击等。 有些人觉得编码规范不重要,其实是大错特错。下面是关于代码格式的一些编码规范,都是Java初学者非常容易忽视的细节:
5013
2020-08-10 16:09:38
这样的Java自学姿势 学废最快
学习Java人数最多。原因是?自然是Java长久占据界编程语言排行榜中榜首,且众多互联网一线大厂如阿里、京东、美团、滴滴等都在使用Java架构。世间的一切,终究逃不过一个“钱”字。
4148
2021-03-05 11:27:54
Java开发线程特点基础知识分享
线程提供的一些不太常用的方法及技术不管是初学者还是高级用户或者是Java专家都需要了解。掌握线程、进程、多线程、并发、并行、同步、异步、线程类常见方法、线程生命周期、线程安全问题、死锁、生产者和消费者等多线程核心知识点。
3335
2021-05-21 17:07:26