本文转发自技术世界原文链接 http://www.jasongj.com/java/nio_reactor/

同步 vs. 异步

同步I/O 

每个请求必须逐个地被处理,一个请求的处理会导致整个流程的暂时等待,

这些事件无法并发地执行。用户线程发起I/O请求后需要等待或者轮询内核I/O操作完成后才能继续执行。

同步意味着一个任务的某个处理过程会对多个线程在用串行化处理

异步I/O 

多个请求可以并发地执行,一个请求或者任务的执行不会导致整个流程的暂时等待。

用户线程发起I/O请求后仍然继续执行,当内核I/O操作完成后会通知用户线程,或者调用用户线程注册的回调函数。

异步则意味着某个处理过程可以允许多个线程同时处理。


阻塞 vs. 非阻塞

阻塞 

某个请求发出后,由于该请求操作需要的条件不满足,请求操作一直阻塞,不会返回,直到条件满足。

非阻塞 

请求发出后,若该请求需要的条件不满足,则立即返回一个标志信息告知条件不满足,而不会一直等待。

一般需要通过循环判断请求条件是否满足来获取请求结果。

需要注意的是,阻塞并不等价于同步,而非阻塞并非等价于异步。

事实上这两组概念描述的是I/O模型中的两个不同维度。

同步和异步着重点在于多个任务执行过程中,后发起的任务是否必须等先发起的任务完成之后再进行。

而不管先发起的任务请求是阻塞等待完成,还是立即返回通过循环等待请求成功。

阻塞和非阻塞重点在于请求的方法是否立即返回(或者说是否在条件不满足时被阻塞)


Java中四种I/O模型

Java最早提供的blocking I/O即是阻塞I/O,

如上文所述,阻塞I/O下请求无法立即完成,则保持阻塞。

阻塞I/O分为如下两个阶段:
阶段1:等待数据就绪。网络 I/O 的情况就是等待远端数据陆续抵达;磁盘I/O的情况就是等待磁盘数据从磁盘上读取到内核态内存中。
阶段2:数据拷贝。出于系统安全,用户态的程序没有权限直接读取内核态内存,因此内核负责把内核态内存中的数据拷贝一份到用户态内存中。

而NIO即是非阻塞I/O,

非阻塞I/O请求包含如下三个阶段

1)socket设置为 NONBLOCK(非阻塞)就是告诉内核,

  当所请求的I/O操作无法完成时,不要将线程睡眠,而是返回一个错误码(EWOULDBLOCK) ,这样请求就不会阻塞。
2)I/O操作函数将不断的测试数据是否已经准备好,如果没有准备好,继续测试,直到数据准备好为止。   整个I/O 请求的过程中,虽然用户线程每次发起I/O请求后可以立即返回,但是为了等到数据,仍需要不断地轮询、重复请求,消耗了大量的 CPU 的资源。
3)数据准备好了,从内核拷贝到用户空间。 一般很少直接使用这种模型,而是在其他I/O模型中使用非阻塞I/O 这一特性。这种方式对单个I/O 请求意义不大,但给I/O多路复用提供了条件。

同时通过NIO实现的Reactor模式即是 I/O复用模型的实现,

I/O多路复用(异步阻塞 I/O)
I/O多路复用会用到select或者poll函数,这两个函数也会使线程阻塞, 但是和阻塞I/O所不同的是,这两个函数可以同时阻塞多个I/O操作。 而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。 从流程上来看,使用select函数进行I/O请求和同步阻塞模型没有太大的区别,甚至还多了添加监视Channel,以及调用select函数的额外操作,增加了额外工作。 但是,使用 select以后最大的优势是用户可以在一个线程内同时处理多个Channel的I/O请求。 用户可以注册多个Channel,然后不断地调用select读取被激活的Channel,即可达到在同一个线程内同时处理多个I/O请求的目的。 而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。 调用select/poll该方法由一个用户态线程负责轮询多个Channel,直到某个阶段1的数据就绪,再通知实际的用户线程执行阶段2的拷贝。 通过一个专职的用户态线程执行非阻塞I/O轮询,模拟实现了阶段一的异步化。

通过AIO实现的Proactor模式即是异步I/O模型的实现。

调用AIO_read 函数,告诉内核描述字,缓冲区指针,缓冲区大小,文件偏移以及通知的方式,然后立即返回。

当内核将数据拷贝到缓冲区后,再通知应用程序。所以异步I/O模式下,阶段1和阶段2全部由内核完成,完成不需要用户线程的参与。

Java I/O模型的更多相关文章

  1. Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式

    原创文章,同步发自作者个人博客,http://www.jasongj.com/java/nio_reactor/ Java I/O模型 同步 vs. 异步 同步I/O 每个请求必须逐个地被处理,一个请 ...

  2. java线程内存模型,线程、工作内存、主内存

    转自:http://rainyear.iteye.com/blog/1734311 java线程内存模型 线程.工作内存.主内存三者之间的交互关系图: key edeas 所有线程共享主内存 每个线程 ...

  3. Java虚拟机内存模型及垃圾回收监控调优

    Java虚拟机内存模型及垃圾回收监控调优 如果你想理解Java垃圾回收如果工作,那么理解JVM的内存模型就显的非常重要.今天我们就来看看JVM内存的各不同部分及如果监控和实现垃圾回收调优. JVM内存 ...

  4. Java I/O 模型的演进

    什么是同步?什么是异步?阻塞和非阻塞又有什么区别?本文先从 Unix 的 I/O 模型讲起,介绍了5种常见的 I/O 模型.而后再引出 Java 的 I/O 模型的演进过程,并用实例说明如何选择合适的 ...

  5. java String 内存模型

    关于java的内存模型,参照以下的一篇文章: https://isudox.com/2016/06/22/memory-model-of-string-in-java-language/

  6. Java虚拟机--内存模型与线程

    Java虚拟机--内存模型与线程 高速缓存:处理器要与内存交互,如读取.存储运算结果,而计算机的存储设备和处理器的运算速度差异巨大,所以加入一层读写速度和处理器接近的高速缓存来作为内存和处理器之间的缓 ...

  7. Java网络编程和NIO详解3:IO模型与Java网络编程模型

    Java网络编程和NIO详解3:IO模型与Java网络编程模型 基本概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32 ...

  8. OSGI 面向Java的动态模型系统

    OSGI (面向Java的动态模型系统) OSGi(Open Service Gateway Initiative)技术是Java动态化模块化系统的一系列规范.OSGi一方面指维护OSGi规范的OSG ...

  9. Java I/O模型从BIO到NIO和Reactor模式(转)

    原创文章,转载请务必将下面这段话置于文章开头处(保留超链接).本文转发自技术世界,原文链接 http://www.jasongj.com/java/nio_reactor/ Java I/O模型 同步 ...

  10. 掌握Java的内存模型,你就是解决并发问题最靓的仔

    摘要:如果编写的并发程序出现问题时,很难通过调试来解决相应的问题,此时,需要一行行的检查代码,这个时候,如果充分理解并掌握了Java的内存模型,你就能够很快分析并定位出问题所在. 本文分享自华为云社区 ...

随机推荐

  1. 数据库 first

    数据库原理 .SQL(DDL.DML) 字符串操作 .数值操作 .日期操作 .空值操作 SQL(基础查询) .SQL(关联查询) SQL(高级查询)  子查询 视图.序列.索引 .约束

  2. Java基础之8个基本类型及基本类型间转换

    8种基本数据类型 Java语言有8种基本数据类型, 分别用于存储整数.浮点数.字符数据和布尔类型数据.需要注意的是: 现在所介绍的仅仅是基本数据类型,后续还会介绍很多非基本数据类型.基本数据类型如图 ...

  3. [TJOI2015]线性代数(网络流)

    [TJOI2015]线性代数(最大权闭合子图,网络流) 为了提高智商,ZJY开始学习线性代数.她的小伙伴菠萝给她出了这样一个问题:给定一个n*n的矩阵B和一个1×n的矩阵C.求出一个1×n的01矩阵A ...

  4. kuangbin专题十六 KMP&&扩展KMP HDU3336 Count the string

    It is well known that AekdyCoin is good at string problems as well as number theory problems. When g ...

  5. maven profile启动项目

  6. SprimgMVC学习笔记(八)—— SpringMVC与前台json数据交互

    一.两种交互形式 可以看出,前台传过来的方式有两种,一种是传json格式的数据过来,另一种就是在url的末尾传普通的key/value串过来,针对这两种方式,在Controller类中会有不同的解析, ...

  7. [Android]Android开发艺术探索第1章笔记

    1.1 Activity 的生命周期全面分析 1.1.1 典型情况下的生命周期分析 onPause: 正在停止,正常情况下紧接着 onStop 就会被调用,然后新的 Activity 执行 onRes ...

  8. hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)

    题目传送门 题目大意:给出n座城市,每个城市都有一个0到9的val,城市的编号是从0到n-1,从i位置出发,只能走到(i*i+1)%n这个位置,从任意起点开始,每走一步都会得到一个数字,走n-1步,会 ...

  9. Log4web独立config配置

    第一步:config配置,独立文件的 <?xml version="1.0" encoding="utf-8"?> <configuratio ...

  10. thinkPHP5.0联表查询和统计文章的图片(栏目文章)数量

    public function index(){ //获取内容列表信息 $res = db('article')->alias('a') ->join('category b', 'b.i ...