Java I/O模型
本文转发自技术世界,原文链接 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模型的更多相关文章
- Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式
原创文章,同步发自作者个人博客,http://www.jasongj.com/java/nio_reactor/ Java I/O模型 同步 vs. 异步 同步I/O 每个请求必须逐个地被处理,一个请 ...
- java线程内存模型,线程、工作内存、主内存
转自:http://rainyear.iteye.com/blog/1734311 java线程内存模型 线程.工作内存.主内存三者之间的交互关系图: key edeas 所有线程共享主内存 每个线程 ...
- Java虚拟机内存模型及垃圾回收监控调优
Java虚拟机内存模型及垃圾回收监控调优 如果你想理解Java垃圾回收如果工作,那么理解JVM的内存模型就显的非常重要.今天我们就来看看JVM内存的各不同部分及如果监控和实现垃圾回收调优. JVM内存 ...
- Java I/O 模型的演进
什么是同步?什么是异步?阻塞和非阻塞又有什么区别?本文先从 Unix 的 I/O 模型讲起,介绍了5种常见的 I/O 模型.而后再引出 Java 的 I/O 模型的演进过程,并用实例说明如何选择合适的 ...
- java String 内存模型
关于java的内存模型,参照以下的一篇文章: https://isudox.com/2016/06/22/memory-model-of-string-in-java-language/
- Java虚拟机--内存模型与线程
Java虚拟机--内存模型与线程 高速缓存:处理器要与内存交互,如读取.存储运算结果,而计算机的存储设备和处理器的运算速度差异巨大,所以加入一层读写速度和处理器接近的高速缓存来作为内存和处理器之间的缓 ...
- Java网络编程和NIO详解3:IO模型与Java网络编程模型
Java网络编程和NIO详解3:IO模型与Java网络编程模型 基本概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32 ...
- OSGI 面向Java的动态模型系统
OSGI (面向Java的动态模型系统) OSGi(Open Service Gateway Initiative)技术是Java动态化模块化系统的一系列规范.OSGi一方面指维护OSGi规范的OSG ...
- Java I/O模型从BIO到NIO和Reactor模式(转)
原创文章,转载请务必将下面这段话置于文章开头处(保留超链接).本文转发自技术世界,原文链接 http://www.jasongj.com/java/nio_reactor/ Java I/O模型 同步 ...
- 掌握Java的内存模型,你就是解决并发问题最靓的仔
摘要:如果编写的并发程序出现问题时,很难通过调试来解决相应的问题,此时,需要一行行的检查代码,这个时候,如果充分理解并掌握了Java的内存模型,你就能够很快分析并定位出问题所在. 本文分享自华为云社区 ...
随机推荐
- C,C++网络编程学习简明指南
C,C++网络编程学习简明指南 1. 扎实的C,C++基础知识 参考资料<C程序设计>,<C++ primer>. 2. TCP/IP协议 经典书是:W.Richard Ste ...
- PHP实现微信公众平台开发—基础篇
PHP实现微信公众平台开发—基础篇 2 1课程介绍 2 2. 微信公众号账号介绍的申请流程详解 2 2.1微信三角色关系 2 2.2信息流的过程 2 2.4微信公众账号的认证 3 2.5订阅号的申请流 ...
- 洛谷P3628 [APIO2010]特别行动队(斜率优化)
传送门 先写出转移方程$$dp[i]=max\{dp[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c\}$$ 假设$j$比$k$更优,则有$$dp[j]+a*(s ...
- 2019年GPLT L2-4 彩虹瓶 比赛题解 中国高校计算机大赛-团体程序设计天梯赛题解
彩虹瓶的制作过程(并不)是这样的:先把一大批空瓶铺放在装填场地上,然后按照一定的顺序将每种颜色的小球均匀撒到这批瓶子里. 假设彩虹瓶里要按顺序装 N 种颜色的小球(不妨将顺序就编号为 1 到 N).现 ...
- C++基础学习4:引用
C++引用(Reference) 引用(Reference)是C++语言相对于C语言的又一个扩充,是C++常用的一个重要内容之一.类似于指针,只是在声明的时候用"&"取代了 ...
- Codeforces Round #534 (Div. 2) D. Game with modulo 交互题
先二分一个区间,再在区间里面二分即可: 可以仔细想想,想明白很有意思的: #include<iostream> #include<cstdio> #include<alg ...
- 2-28 switch
- 电路中IC器件电压符号的解释
在电子芯片.运算处理器等集成电路行业中,存在多种电压.常用的的有:VDDQ->The supply voltage to output buffers of a memory chip 存储芯片 ...
- C语言中函数声明、形参、实参
函数原型: 原型prototype是函数的声明:描述了函数的返回值与参数: 函数原型说明了两点: 1.该函数的返回值 2.该函数的参数及其类型 ++++++++++++++++++++++++++++ ...
- TP框架中D方法和M方法
D()和M()方法的区别: D和M的区别主要在于 M方法不需要创建模型类文件,M方法不会读取模型类,所以默认情况下自动验证是无效的,但是可以通过动态赋值的方式实现 而D方法必须有创建模型类. 我们可以 ...