java并发编程之美pdf百度云,七(3)

Reactor(也叫Dispacher)线程模型不再为每个请求创建线程 ,而是基于 I/O 复用模型,多个请求连接同一个阻塞对象,应用程序只需要在一个阻塞对象等待,无需阻塞等待所有连接。当请求中有数据,操作系统通知应用程序,线程从阻塞状态返回,开始进行业务处理,一个线程可以处理多个连接的业务,如图:

在这里插入图片描述

先来理解两个概念

  • Reactor:即图中的ServiceHandler,Reactor负责监听和事件分发,分发给适当的处理程序来对 IO 事件做出反应, 在单独的线程中执行。就像公司的电话接线员,它接听来自客户的电话并将线路转移到适当的联系人;

  • Handlers:Reactor监听到IO事件,需要调度应用程序来处理即:Handler,Handler是真正处理 I/O 事件的程序,类似于接电话的实际的人员。

简单理解就是Reactor线程模型有两个角色 ,一个负责接待请求(Reactor), 一个负责处理请求(Handlers)

Reactor单线程

另外Reactor有三种模式 :Reactor 单线程模型 、单 Reactor 多线程模型 、

Reactor主从多线程模型 。Netty框架是基于主从Reactor多线程模型进行改进(多个主Reactor)。 下面是Reactor单线程模型,如图:

在这里插入图片描述

Reactor单线程模型工作流程如下

  1. Reactor 通过 Select 监控客户端请求,收到事件后通过 Dispatch 进行请求分发

  2. 如果是请求事件是建立连接,则由 Acceptor 通过 accept 处理连接请求,然后创建一个 Handler 。

  3. 如果不是连接事件,则 Reactor 会分发调用连接对应的 Handler 来处理请求

  4. Handler 会完成数据read,进行业务处理最后通过 Send 将响应结果返回给 Client

Reactor单线程模型优点是模型简单,缺点也是比较明显

  • 线程单一,如果并发高,业务处理慢,很容易导致性能瓶颈,

  • 如果线程故障或终止,整个系统不可用

所以这种模型不太适合高并发场景,和业务处理比较耗时的场景。

Reactor多线程

接下来看一下单Reactor 多线程模型 ,先看图把:

在这里插入图片描述

Reactor多线程模式工作流程如下

  1. Reactor 通过 Select 监控客户端请求,收到事件后通过 Dispatch 进行请求分发

  2. 如果是请求事件是建立连接,则由 Acceptor 通过 accept 处理连接请求,然后创建一个 Handler 。

  3. 如果不是连接事件,则 Reactor 会分发调用连接对应的 Handler 来处理请求

  4. Handler 只负责响应事件,不做具体业务处理,通过 Read 读取数据后,会分发给后面的 Worker 线程池进行业务处理

  5. Worker 线程池会分配独立的线程完成真正的业务处理,将响应结果发给 Handler 进行处理。

  6. Handler 收到响应结果后通过 Send 将响应结果返回给 Client。

这种模型引入了线程池,Reactor线程负责接收连接和响应事件,具体IO事件交给线程池分配的线程处理。优点是可以充分利用CPU,提供整体性能,但是Reactor承担所有的事件监听和分发,容易成为性能瓶颈,多线程的数据共享也是一个问题。

主从Reactor多线程

单Reactor多线程的问题是Reactor在单线程中执行可能会成为瓶颈,那么主从Reactor多线程就解决了这个问题 ,看图:

在这里插入图片描述

主从Reactor多线程模式工作流程如下

  1. Reactor 主线程 MainReactor 对象通过 Select 监听连接事件,收到事件后通过 Acceptor 接收,处理建立连接事件。

  2. Acceptor 处理建立连接事件后,MainReactor 将连接分配 Reactor 子线程给 SubReactor 进行处理。

  3. SubReactor 将连接加入连接队列进行监听,并创建一个 Handler 用于处理各种连接事件,

  4. 当有新的事件发生时,SubReactor 会调用连接对应的 Handler 处理

  5. Handler 通过 Read 读取数据后,会分发给后面的 Worker 线程池进行业务处理

  6. Worker 线程池会分配独立的线程完成真正的业务处理,将响应结果发给 Handler 进行处理

  7. Handler 收到响应结果后通过 Send 将响应结果返回给 Client

这种模式的优点比较明显,Reactor主线程只需要接收新连接,子线程完成后续的业务处理,Reactor的压力得到了分担。这种模型在许多项目中广泛使用,包括 Nginx 主从 Reactor 多进程模型,Memcached 主从多线程,Netty 主从多线程模型的支持。

Netty的线程模型

========================================================================

Netty是基于主从Reactor多线程模型实现,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果,Netty线程模型如下图:

在这里插入图片描述

Netty线程模型中有两个Group,分别是Boss Group和Worker Group,的BossGroup 用于Accetpt连接建立事件并分发请求,workerGroup用于处理I/O读写事件和业务逻辑。其中关键组件如下

  • Channel

Netty网络通信的组件,能够用于执行网络IO操作。

  • Selector

Netty基于Selector对象实现I/O多路复用,即:一个线程可以监听多个连接的Channel事件, 当channel向Selector注册 后,Selector 就可以自动不断地查询(select) 注册的Channel是否有已就绪的I/O事件(例如可读, 可写, 网络连接完成等)。

  • NioEventLoop

NioEventLoop表示一个不断循环的执行处理任务的线程, 每个NioEventLoop 都有一个 selector。用于监听注册的Channel的IO事件。

NioEventLoop中维护一个线程和任务队列,支持异步提交任务,线程启动时会调用NioEventLoop的run方法,执行IO和非IO任务。 其中IO任务由prossSelectedKeys触发,非IO任务由runAlltasks触发。

  • NioEventLoopGroup

NioEventLoopGroup用来管理EventLoop,可以理解为线程组,内部维护了一组线程

Netty线程模型工作流程如下:

  1. Boss Group里面的NioEventLoop会轮询accept事件,遇到有新的连接,就生成NioSocketChannel,并把这个Channel注册到Worker Group的Selector上

  2. Worker Group轮询read和write事件,在可读或者可写条件满足时,就进行处理

Worker Group和Boss Group都是通过里面的NioEventLoop来操作的。NioEventLoop中维护了一个线程和任务队列,支持异步提交执行任务,线程启动时会调用NioEventLoop的run方法

每个Boss NioEventLoop循环执行的步骤有3步

  1. 轮询检查accept事件

  2. 处理accept事件,与client建立连接, 生成NioSocketChannel, 并将其注册到某个 Worker NIOEventLoop上的 selector ,这样Channel的IO事件就交给WorkGroup去监听了。

  3. 最后执行一个runAllTasks方法,用于处理任务队列中的任务

每个 Worker NIOEventLoop 循环执行的步骤:

  1. 轮询read, write 事件

  2. 处理 I/O 事件, 即 read, write 事件, 再对应NioSocketChannel 处理

  3. 最后执行一个runAllTasks方法,用于处理任务队列中的任务

总结

本篇文件的内容主要介绍了一下Netty,以及三种 Reactor 线程模型,以及Netty的线程模型,Netty的线程模型主要是基于主从Reactor多线程模型升级,在下一章节我们来实战Netty。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

Java核心知识

  • Spring全家桶(实战系列)

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

  • 其他电子书资料

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

[外链图片转存中…(img-vFs4Qe7W-1713445485691)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值