Java NIO学习与记录(六): NIO线程模型
NIO线程模型
上一篇说的是基于操作系统的IO处理模型,那么这一篇来介绍下服务器端基于IO模型和自身线程的处理方式。
一、传统阻塞IO模型下的线程处理模式
这种处理模型是基于阻塞IO进行的,上一篇讲过,阻塞IO会阻塞每一个IO操作,直到事件就绪,下面来看下阻塞IO下的服务端线程模型:

图1
如上图所示,该线程模型基于阻塞IO模型实现,针对每个请求都需要抽出来一个线程进行处理读入数据、业务处理数据、返回响应结果给客户端,这个过程中读、写操作均会阻塞,且跟业务处理串行执行,该模式下,并发量过大时会大量创建线程,发生的大量上下文切换,从而导致CPU资源占用过大,当连接建立后,若当前线程暂无可读数据,则线程会一直阻塞在读操作上,造成线程资源浪费,即便使用线程池进行优化,虽然避免了大量创建线程,但也会出现线程资源浪费的问题,高并发下可能会造成排队、响应不及时的问题。
具体BIO服务器的实现参考:SocketChannel与BIO服务器
二、基于IO多路复用模型下的Reactor线程模型
利用操作系统IO多路复用模型实现,Java对其调用进行了封装(select等),这里先不探讨怎么利用java的api去调用,先来看看它的基本流程是怎样的,Reactor模式下的县线程模型又会根据线程数量、线程池数量的不同,细分了三种线程模型。
2.1:单Reactor单线程模型
这是最简单的Reactor模型,整个过程中的事件处理全部发生在一个线程里:

图2
上图示意就是个简单的IO多路复用单Reactor单线程处理模型,流程如下:
①Reactor对象通过select监听客户端的请求事件,收到事件消息后通过dispatch进行任务分发。
②如果是建连请求,则交由Acceptor对象处理连接请求,然后创建一个Handler对象继续完成后续处理
③若不是建连请求,则dispatch会调用对应连接的Handler进行处理,Handle负责完成连接成功后的后续处理(读操作、写操作、业务处理等)
此模型很简单,易于理解,但是存在一定的问题,比如单线处理程模型下,无法发挥多核CPU的性能,如果Handler上的业务处理很慢,则意味着整个程序无法处理其他连接事件,造成性能问题。
适用于业务处理快速、客户端连接较少的情况。
2.2:单Reactor多线程模型
相较于上面的模型,对业务处理模块进行了异步处理,流程图如下:

图3
上图示意属于单Reactor多线程处理模型,流程如下:
①Reactor对象通过select监听客户端的请求事件,收到事件消息后通过dispatch进行任务分发。
②如果是建连请求,则交由Acceptor对象处理连接请求,然后创建一个Handler对象继续完成后续处理
③若不是建连请求,则dispatch会调用对应连接的Handler进行处理,Handle负责完成连接成功后的读操作,读出来数据后的业务处理部分交由线程池异步处理,业务处理完成后发送给Handler处理完成的消息,然后再由Handler发送处理响应信息给对应的Client。
本模型充分利用了多核CPU的处理能力,降低了由业务处理引起的性能问题,Reactor线程仅负责接收连接、读写操作。但是Reactor除了负责连接处理外仍然负责读写操作,大量的请求下仍然可能仍然存在性能问题。
2.3:主从Reactor多线程模型
这个模型中将会独立出另一个Reactor对象来处理非连接处理的其他处理,命名为从Reactor(SubReactor),流程图如下:

图4
上图示意属于主从Reactor多线程处理模型,流程如下:
①主Reactor对象(MainReactor)通过select监听客户端的连接事件,收到连接事件后交由Acceptor处理。
②Acceptor处理完成后,MainReactor将此连接分配给SubReactor处理,SubReactor将此连接加入连接队列进行事件监听并建立Handler进行后续的各种操作,同上面的模型一致,SubReactor会监听新的事件,如果有新的事件发生,则调用Handler进行相应的处理。
③Handler读出来数据后的业务处理部分交由线程池异步处理,业务处理完成后发送给Handler处理完成的消息,然后再由Handler发送处理响应信息给对应的Client。
该模型存在两个线程分别处理Reactor事件,主线程只负责处理连接事件,子线程只负责处理读写事件,这样主线程可以处理更多的连接,而不用关心子线程里的读写处理是否会影响到自己。目前这种模型被广泛使用在各种项目中(如Netty、Memcached等)。
以上的线程模型都是基于同步IO,异步IO这里不作说明,目前大部分项目都采用IO多路复用(同步非阻塞)的模式进行(该模式下又分成了上述3种线程处理模型)。
下一篇将会针对IO多路复用下的三种线程模型,介绍下Selector,以及利用Selector来写一下具体的实现代码。
Java NIO学习与记录(六): NIO线程模型的更多相关文章
- Java NIO学习与记录(八): Reactor两种多线程模型的实现
Reactor两种多线程模型的实现 注:本篇文章例子基于上一篇进行:Java NIO学习与记录(七): Reactor单线程模型的实现 紧接着上篇Reactor单线程模型的例子来,假设Handler的 ...
- Java NIO 学习笔记(六)----异步文件通道 AsynchronousFileChannel
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- Java NIO学习系列四:NIO和IO对比
前面的一些文章中我总结了一些Java IO和NIO相关的主要知识点,也是管中窥豹,IO类库已经功能很强大了,但是Java 为什么又要引入NIO,这是我一直不是很清楚的?前面也只是简单提及了一下:因为性 ...
- Java NIO学习系列五:I/O模型
前面总结了很多IO.NIO相关的基础知识点,还总结了IO和NIO之间的区别及各自适用场景,本文会从另一个视角来学习一下IO,即IO模型.什么是IO模型?对于不同人.在不同场景下给出的答案是不同的,所以 ...
- Android(java)学习笔记267:Android线程池形态
1. 线程池简介 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...
- Lucene.net(4.8.0) 学习问题记录六:Lucene 的索引系统和搜索过程分析
前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...
- Android(java)学习笔记211:Android线程池形态
1. 线程池简介 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...
- Java并发学习(一):进程和线程
好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 前言 俗话说得好"一人 ...
- Java基础学习总结(88)——线程创建与终止、互斥、通信、本地变量
线程创建与终止 线程创建 Thread类与 Runnable 接口的关系 public interface Runnable { public abstract void run(); ...
随机推荐
- QTcpSocket-Qt使用Tcp通讯实现服务端和客户端
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QTcpSocket-Qt使用Tcp通讯实现服务端和客户端 本文地址:https:// ...
- 分布式java应用基础与实践
始读于2014年4月30日,完成于2014年6月6日15:43:39. 阿里巴巴高级研究员林昊早年的书了,这些理论放到今天估计工作一两年的人都耳熟能详了,我个人很早以前就知道此书一直没有找到资源, ...
- [转]go中的main函数和init函数
Go里面有两个保留的函数:init函数(能够应用于所有的package)和main函数(只能应用于package main).这两个函数在定义时不能有任何的参数和返回值.虽然一个package里面可以 ...
- Redis数据结构(六)
Redis数据结构(Sort-set)(游戏排名和微博热点话题排名上应用): 特点:可存储有序但不重复的数据,根据分数指定存储顺序 1 Sort-set和Set的区别: (1)sort的每个成员都是以 ...
- 变分贝叶斯VBEM 由浅入深
变分贝叶斯EM指的是变分贝叶斯期望最大化(VBEM, variational Bayes expectation maximization),这种算法基于变分推理,通过迭代寻找最小化KL(Kullba ...
- util:properties
示例 <util:properties id="db" location="classpath:db.properties" /> 全部属性 功能概 ...
- java文件的读写程序代码
package textopen; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutp ...
- xib下这种方式创建cell
这种方法在iOS5.0之前是不能够创建成功的. MEConvertListTableViewCell *cell = [tableView dequeueReusableCellWithIde ...
- [转]细说 ASP.NET Cache 及其高级用法
本文转自:http://www.cnblogs.com/fish-li/archive/2011/12/27/2304063.html 阅读目录 开始 Cache的基本用途 Cache的定义 Cach ...
- URAL1991 The battle near the swamp 2017-04-12 18:07 92人阅读 评论(0) 收藏
The battle near the swamp Gungan: Jar Jar, usen da booma! Jar Jar: What? Mesa no have a booma! Gun ...