关于JAVA BIO、NIO、AIO的简介
参考内容
NIO、BIO、AIO简介
https://www.cnblogs.com/welen/articles/5385837.html
https://www.cnblogs.com/diegodu/p/6823855.html
https://www.cnblogs.com/ygj0930/p/6543960.html
https://blog.youkuaiyun.com/ty497122758/article/details/78979302
IO多路复用及select 函数
https://www.cnblogs.com/liulaoshi/p/6984840.html
https://blog.youkuaiyun.com/sinat_35297665/article/details/78172376
文件描述符和文件句柄
https://blog.youkuaiyun.com/qq_36255988/article/details/80578585
https://www.cnblogs.com/ChunJian-YANG/p/5322041.html
由于本人对这些内容理解的还不够深,所以不敢写的太深,以免误导人。只写一些本人已经理解的内容。欢迎各位大大给予批评指正!
按照《Unix网络编程》的划分,IO模型分为阻塞IO、非阻塞IO、IO复用、信号驱动IO(不做介绍)、异步IO。下面将的BIO、AIO、NIO是针对于操作系统来说的,如果别人问的是“JAVA 的AIO、BIO、NIO" ,答案是有区别的。
1.同步阻塞I/O模型
用户线程在内核进行I/O操作时被阻塞。
打个比方,I/O操作比如图书馆管理员从图书馆把书借出去,或者将还回来的书归还到书架。
而管理员小王就是一个线程。记住条件,该图书馆只有小王一个图书管理员。
平时的工作状态是:
(A、B两同学来借书)
A同学:小王,我来借《金瓶梅》。小王:好嘞,您稍等,我去拿。
(A同学翘首以盼,B同学干等。。。)
过一会。。。
小王:给你《金瓶梅》。A同学:好的。
B同学:我来借《霸道总裁爱上我之前世孽缘》。。。
2.同步非阻塞I/O模型
A、B两同学发现,告诉小王后,到小王把书拿来,中间有一段时间要干等着,很无聊。
于是第二天:
A同学:小王,我来借《金瓶梅》。我先去趟厕所,一会再来问下。小王:好嘞,您稍等。
过一会。。。
A同学:我的书(金)拿来没?小王:没呢。
过一会。。。
A同学:我的书(金)拿来没?小王:没呢。
过一会。。。
A同学:我的书(金)拿来没?小王:拿来了,给你。
B同学:我来借。。。
小结:第一个模式是最简单,最原始的模型。
第一个和第二个的区别在于,A同学告诉小王要借的书之后,立马得到应答,然后就可以去做别的事(socket设置为NONBLOCK,非阻塞)。但是需要A同学过一会再来问(轮巡)。由于这种情况,需要不断的轮询,重复请求,消耗了大量的CPU资源。一般很少直接使用这种模型。
3.I/O多路复用模型
小王今年干的不错,年终奖发了一个笔记本。(真的是笔记本,封皮是流星花园F4)。
由于小王工作时既要跟A交流,又要跟B、C、D交流,沟通成本很大,影响他搬书效率。
小王眉头一皱,计上心来。把F4笔记本放在前台,谁来借书谁登记。于是。。
A同学登记:A借《金瓶梅》。
B同学登记:B借《霸道总裁爱上我之前世孽缘》。
(小王只顾搬书就行了,搬来的书放在前台。借书的人自己取)
小结:用户首先将需要进行IO操作的socket添加到select中,然后阻塞等待select系统调用返回。当数据到达时,socket被激活,select函数返回。用户线程正式发起read请求,读取数据并继续执行。这里的select 函数被比喻成F4笔记本。这个模型的优势在于仅仅是小王一个人(单线程),就可以处理多个IO请求。在前两个模型里,小王在处理A同学的请求时,B同学是插不上话的。但是这个模式仍然需要借书的人自己不断查看自己的书是否已经到前台了。为了改善用户体验,小王一咬牙买了个智能音箱–小爱同学,用来替代笔记本。于是有了IO多路复用模型的Reactor模式
4.I/O多路复用模型Reactor模式
小王:以后借什么书,就告诉这个小爱同学,书就位之后,小爱同学也会通知大家。
A同学:小爱同学,悄悄告诉你,我来借《金瓶梅》。小爱:收到。
B同学:小爱同学,悄悄告诉你,我来借《霸道总裁爱上我之前世孽缘》。小爱:收到。
(小王搬书中。。。)
(小王搬书完毕。。。)
小爱同学大声喊道:A同学,请来取你的《金瓶梅》!!!B同学,请来取你的《霸道总裁爱上我之前世孽缘》
小结:虽然(3:多路复用模式)允许单线程内处理多个IO请求,但是每个IO请求的过程还是阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要长。如果用户线程只注册自己感兴趣的socket或者IO请求,然后去做自己的事情,等到数据到来时再进行处理,则可以提高CPU的利用率,这就是4:Reactor模式做的事情。
5.真正的异步IO----Proactor模式
上面说的几种模式都不是真正意义上的异步IO。即使是Reactor 模式也只能算是异步阻塞IO。因为
在select函数上还是阻塞的。linux 的AIO 首次出现是在 2.5的版本上。
说人话:毕竟小爱同学通知A和B之后,还是需要他们两个亲自来前台取书,而取书需要排队。
“真正”的异步IO需要操作系统更强的支持。在IO多路复用模型中,事件循环将文件句柄的状态事件
通知给用户线程,由用户线程自行读取数据、处理数据。而在异步IO模型中,当用户线程收到通
知时,数据已经被内核读取完毕,并放在了*用户线程指定的缓冲区*内,内核在IO完成后通知用户
线程直接使用即可。
说人话:Proacotr 模式就是 图书馆招了很多个小王,小王一、小王二。。。小王八。。。
借书的人去小爱同学那里登记完要借的书之后,还告诉了她,自己坐在什么位置等。众小王取到之后
,根据登记的座位,把书亲自送到借书人的手上。
总结:以上内容是本人看过n篇博客之后整理出来的,内容比较浅显。更深更详细的内容,请参见各位大大的博客。