常见JAVA IO/NIO模型[通俗易懂]

常见JAVA IO/NIO模型[通俗易懂]我们常见的IO模型有:阻塞IO模型、非阻塞IO模型、多路复用IO模型、信号驱动IO模型、异步IO模型;下面我们就简单介绍一下以上IO模型。1、阻塞IO模型最传统的一种IO模型,即在读写数据过程中会发生阻塞现象。当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核…

大家好,又见面了,我是你们的朋友全栈君。

我们常见的IO模型有:阻塞 IO 模型、非阻塞 IO 模型、多路复用 IO 模型、 信号驱动 IO 模型、异步 IO 模型;下面我们就简单介绍一下以上IO模型。

1、阻塞 IO 模型

最传统的一种IO 模型,即在读写数据过程中会发生阻塞现象。当用户线程发出IO 请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block 状态。典型的阻塞IO 模型的例子为:data = socket.read();如果数据没有就绪,就会一直阻塞在read 方法。

2、非阻塞 IO 模型

当用户线程发起一个read 操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error 时,它就知道数据还没有准备好,于是它可以再次发送read 操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。所以事实上,在非阻塞IO 模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞IO不会交出CPU,而会一直占用CPU。典型的非阻塞IO 模型一般如下:

while(true){
data = socket.read();
if(data!= error){
处理数据
break;
}
}

但是对于非阻塞IO 就有一个非常严重的问题,在while 循环中需要不断地去询问内核数据是否就绪,这样会导致CPU 占用率非常高,因此一般情况下很少使用while 循环这种方式来读取数据。

3、多路复用 IO 模型

    多路复用IO 模型是目前使用得比较多的模型。Java NIO 实际上就是多路复用IO。在多路复用IO模型中,会有一个线程不断去轮询多个socket 的状态,只有当socket 真正有读写事件时,才真正调用实际的IO 读写操作。因为在多路复用IO 模型中,只需要使用一个线程就可以管理多个socket,系统不需要建立新的进程或者线程,也不必维护这些线程和进程,并且只有在真正有socket 读写事件进行时,才会使用IO 资源,所以它大大减少了资源占用。在Java NIO 中,是通过selector.select()去查询每个通道是否有到达事件,如果没有事件,则一直阻塞在那里,因此这种方式会导致用户线程的阻塞。多路复用IO 模式,通过一个线程就可以管理多个socket,只有当socket 真正有读写事件发生才会占用资源来进行实际的读写操作。因此,多路复用IO 比较适合连接数比较多的情况。

  另外多路复用IO 为何比非阻塞IO 模型的效率高是因为在非阻塞IO 中,不断地询问socket 状态时通过用户线程去进行的,而在多路复用IO 中,轮询每个socket 状态是内核在进行的,这个效率要比用户线程要高的多。不过要注意的是,多路复用IO 模型是通过轮询的方式来检测是否有事件到达,并且对到达的事件逐一进行响应。因此对于多路复用IO 模型来说,一旦事件响应体很大,那么就会导致后续的事件迟迟得不到处理,并且会影响新的事件轮询。

4、信号驱动 IO 模型

在信号驱动IO 模型中,当用户线程发起一个IO 请求操作,会给对应的socket 注册一个信号函数,然后用户线程会继续执行,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用IO 读写操作来进行实际的IO 请求操作。

5、异步 IO 模型

     异步IO 模型才是最理想的IO 模型,在异步IO 模型中,当用户线程发起read 操作之后,立刻就可以开始去做其它的事。而另一方面,从内核的角度,当它受到一个asynchronous read 之后,它会立刻返回,说明read 请求已经成功发起了,因此不会对用户线程产生任何block。然后,内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程
发送一个信号,告诉它read 操作完成了。也就说用户线程完全不需要实际的整个IO 操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示IO 操作已经完成,可以直接去使用数据了。也就说在异步IO 模型中,IO 操作的两个阶段都不会阻塞用户线程,这两个阶段都是由内核自动完成,然后发送一个信号告知用户线程操作已完成。用户线程中不需要再次调用IO 函数进行具体的读写。这点是和信号驱动模型有所不同的,在信号驱动模型中,当用户线程接收到信号表示数据已经就绪,然后需要用户线程调用IO 函数进行实际的读写操作;而在异步IO 模型中,收到信号表示IO 操作已经完成,不需要再在用户线程中调用IO 函数进行实际的读写操作。
注意,异步IO 是需要操作系统的底层支持,在Java 7 中,提供了Asynchronous IO。

 

 

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/133540.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • access数据库表的创建_access数据库sql语句大全

    access数据库表的创建_access数据库sql语句大全在Access中使用sql语句创建表时指定字段类型长度为255的文本varchar长度为20的文本varchar(20)日期时间datetime数字byte或smallint或integer,或bit自动编号:counter(1,1)外健:constraint外健名主键:primarykey小数:numeric单精度:real双精度:float备注:m

  • stn专线和otn有什么区别_stn云专线是什么意思?

    stn专线和otn有什么区别_stn云专线是什么意思?云专线产品是指依托于STN(智能传送网),为客户提供灵活业务接入、灵活带宽、高可靠性及端到端质量保障的专线产品。STN云专线产品描述:依托于STN(智能传送网),为客户提供灵活业务接入、灵活带宽、高可靠性及端到端质量保障的二层以太专线产品。STN(SmartTransportNetwork)智能传送网,采用JIPRAN及PTN技术相结合发展起来的—种增强型分组组网技术,该技术可叠加在移动业…

    2022年10月19日
  • 【NOIP2012提高组】国王游戏[通俗易懂]

    【NOIP2012提高组】国王游戏[通俗易懂]题目描述恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。国王不希望某一个大臣获得特别多…

  • 不堪入目!某酒店社交App充斥大量涉黄信息

    点击上方“全栈程序员社区”,星标公众号重磅干货,第一时间送达          正文    近年来网…

  • 《天下强汉》3、强汉骄子,双星闪耀——卫青霍去病的华美人生[通俗易懂]

    《天下强汉》3、强汉骄子,双星闪耀——卫青霍去病的华美人生[通俗易懂]【档案】  姓名:卫青,字仲卿;霍去病,号嫖姚  生卒:卫青,约公元前157年—公元前106年;霍去病,公元前141年—公元前117年  性别:男  籍贯:河东平阳人(今山西临汾市西南)  家庭出身:私生子、奴隶(卫青);外戚(霍去病)  学历:无师自通的军事天才  相貌:疏眉朗目,高大俊美,英武矫健  秘密武器:武刚车  经典战役:龙城之战,雁门之战,河南之战,突袭右贤王之战,漠南之战,河西之战…

  • Makefile中的patsubst函数[通俗易懂]

    $(patsubst原模式,目标模式,文件列表)如:在$(patsubst%.c,%.o,$(dir))中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o$(patsubstpattern,replacement,text)表示寻找text中符合模式pattern的字,用replacement替换他们。%是Makefile的通配符…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号