线程模型
线程模型
1.传统服务设计模型
特点:
- 通过阻塞I/O来获取数据
- 每个连接都需要独立的线程来完成业务输入、数据处理、数据返回
存在的问题:
- 1.当并发数很大时,需要创建大量线程,占用了很多系统资源。
- 2.连接创建后,如果连接中没有数据可读,线程会被阻塞,操作线程资源浪费。
2. NIO分发模型
分发模型具有以下几个机制:
- 将一个完整处理过程分解为一个个细小的任务。
- 每个任务执行相关的动作且不产生阻塞。
- 在任务执行状态被触发时才会去执行,例如,只在有数据时才会触发读操作。
3.事件驱动模型
事件驱动模型简单来说,就是当有事件来临时,任务才会被触发执行。
事件驱动的编程难度相对较高,它必须为服务设计多个逻辑状态,以便跟踪和中断恢复。这些逻辑状态也代表着相应的事件。
在Java NIO中,有以下逻辑状态:
- OP_ACCEPT:接收连接事件,表示服务器监听到了客户连接。
- OP_CONNECT:连接就绪事件,表示客户与服务器的连接已经建立
- OP_READ:读就绪事件,表示通道中已有可读的数据。
- OP_WRITE:写就绪事件,表示已经可以向通道写数据了。一般写就绪事件发生时机:当我们需要主动的向通道中写数据时,一般来说有两种方式:1.直接从Selector中拿到通道,然后直接写;2.将需要写的数据附加在SelectionKey上,然后调用key.interestOps(SelectionKey.OP_WRITE),来将该key标记,当下次select时,该key会触发写操作。
Java NIO 示例
4.Reactor模型
有多种叫法,分别是反应器模式、分发者模式(Dispatcher)、通知者模式(Notifier)。
针对传统阻塞I/O模型的缺点,提出了两个解决方案:
-
基于IO复用模型:多个连接公用一个阻塞对象,应用程序只需要在一个阻塞对象等待,无需阻塞等待所有连接,当某个连接有新的数据可以处理时,操作系统通知应用程序从阻塞状态返回,开始进行业务处理。
-
基于线程池复用线程资源:不必为每个连接都创建线程,将连接完成后的业务处理任务交给线程来进行处理,一个线程可处理多个连接的业务。
优点:
- 响应快
- 可以最大程度的避免复杂的多线程及同步问题,并且避免了线程/进程切换开销
- 扩展性好,可以通过增加Reactor实例个数来充分利用CPU资源
- 可复用性高,Reactor模型与具体事件处理逻辑无关,具有很高的复用性
4.1 单Reactor单线程模型
所有的处理流程仅在一个线程中完成,Reactor、Acceptor、Handler仅做了代码上的划分。
处理流程如下:
- 客户端发送请求,服务端Reactor监听到请求后,调用dispatch处理
- 如果是连接事件,则调用Acceptor处理
- 如果是读写事件,则调用Handler处理
使用案例:Redis
4.2 单Reactor多线程模型
该模型下监听、读写事件仍然由Reactor线程来处理,将耗时的业务处理流程交给了线程池来处理。
处理流程如下:
- 客户端发送请求,服务端Reactor线程监听到事件,调用dispatch处理
- 如果是连接事件,则交给Acceptor来处理
- 如果是读事件,则调用Handler读取到数据,然后交给Worker线程来进行业务逻辑处理,然后将操作结果返回给Reactor
- 如果是写事件,则Reactor调用Handler执行写操作
4.3 主从Reactor多线程模型
- 客户端发起连接请求,主Reactor通过Acceptor监听到连接请求。
- Acceptor从多个副Reactor中挑选一个出来,然后将新连接交给该副Reactor。
- 将该连接注册到副Reactor单独维护的Selector中。
- 当连接可读时,副Reactor通过Handler来执行读操作,然后将处理数据的过程放到Worker来执行。
- Workder线程处理完成后,Worker将返回操作结果给副Reactor,副Reactor再将操作结果返回给用户。
其中主Reactor是单线程的,副Reactor由多个线程组成,Workder线程池由多个线程组成。
优点:
- 主Reactor和副Reactor分工明确交互简单,主Reactor只需要接受新连接,副Reactor负责监听连接读写事件
缺点:
- 编程复杂度较高
使用案例:Netty、Nginx 等
__EOF__

本文作者:ZOLMK
本文链接:https://www.cnblogs.com/zolmk/p/17537559.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/zolmk/p/17537559.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?