BIO、NIO、AIO区别

梦想不抛弃苦心追求的人,只要不停止追求,你们会沐浴在梦想的光辉之中。再美好的梦想与目标,再完美的计划和方案,如果不能尽快在行动中落实,最终只能是纸上谈兵,空想一番。只要瞄准了大方向,坚持不懈地做下去,才能够扫除挡在梦想前面的障碍,实现美好的人生蓝图。BIO、NIO、AIO区别,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、BIO:Blocking IO,阻塞io,效率很低,因为经常被阻塞

1、工作原理图

在这里插入图片描述

2、java代码

2.1、服务端代码:

在这里插入图片描述

服务端创建ServerSocket对象,绑定地址和端口。进入循环等待被链接(没有链接则一直阻塞在ss.accept()这),一旦有客户端连接上了,通过ss.accept()方法,重启线程去执行(之所以重启线程因为为了高并发着想)

2.2、客户端代码

在这里插入图片描述

3、BIO阻塞的原因

  1. accept是阻塞方法,没有客户端进来一直被阻塞
  2. read是阻塞方法,客户端只是连接了,但是啥也没写,服务端这边便阻塞在read方法这
  3. write是阻塞方法,服务端啥也没写则阻塞在这

4、使用场景:

当客户端比较少时可以用,因为写法简单

二、NIO:

1、New Non-Blocking:非阻塞IO(单线程模式)

1.1、工作原理图

在这里插入图片描述

服务端主线程中有个selector(选择器)一共干两件事:一件事是每隔一段时间看看有没有新的客户端要连上来,如果有则把客户端连到服务器。二是看看已经连上服务器的客户端与服务端之间有没有读写操作,如果有进行处理。也就是一个线程把所有事都干了

1.2、java代码

在这里插入图片描述
1、ssc.configureBlocking(false):设置为非阻塞
2、ssc.register():注册选择器要做的事情,这个地方做的事情是看看有没有客户端要连上来
3、selector.select():是阻塞方法,有客户端要连接了则往下走
4、服务端ServerSocket可以看成一个带有很多插座的面板。keys相当于selector往服务端各个插座上注册的监听器的集合,当有客户端要往上连接时,就把这个连接事件放到keys里面,然后去循环keys,并且处理完一定要remove(如果不remove则下次还会再处理这个事件)。handle是具体处理过程

在这里插入图片描述
在这里插入图片描述
1、key.isAcceptable==true说明有客户端想连上来,设置成false目的是取消阻塞
2、sc.register():这个地方要做的的事情是看看以连上的客户端有没有写操作(相对于服务端是读)
3、key.isReadable==true说明以连上的客户端有写操作

1.3、使用场景

因为一直都是selector单线程执行,只要有一个地方被阻塞,整个程序就运行不下去了,再加上ByteBuffer复杂,所以很少有人用nio单线程模式
ByteBuffer是个特别复杂的东西,所以后来netty应运而生

2、NIO-reactor(NIO响应式编程模式)

2.1、工作原理图

在这里插入图片描述
selector干两件事:一是每隔一段时间看看有没有新的客户端要连上来,如果有则把客户端连到服务器。二是当连接完的客户端要读写时,把这些读写操作交给线程池去干(这样就不再是单线程了)

三、AIO:异步IO

工作原理图

在这里插入图片描述
有客户端要连的时候操作系统通知回调函数,然后回调函数去处理;当有读写操作的时候,继续调跟读写有关的回调函数。但是依然有ByteBuffer,所以不太常用

四、三者比较

1、BIO(同步阻塞IO):

无论是连接还是读写操作只要是没完成就阻塞(连接、读、写方法均为阻塞方法)。因为经常被阻塞,所以效率很低,不太常用;但写法简单,用户量少是可以考虑使用

2、NIO(同步非阻塞IO):

都是selector每隔一段时间去轮询看看有没有要处理的连接操作或读写操作(单线程selector自己处理读写操作、多线程selector把读写操作给线程池)。但是ByteBuffer变态,所以不太常用
在这里插入图片描述

每次selector连接完一个请求时便会生成一个channel与客户端一一对应,客户端与服务端的读写操作在channel中进行,利用byetbuffer可以操作交互的数据也可存储数据,不会像stream因为交互完了而立马消失了

3、AIO(异步非阻塞IO):

当有客户端要连的时候操作系统通知回调函数,然后回调函数去处理;当有读写操作的时候,继续调跟读写有关的回调函数。但是依然有ByteBuffer,所以不太常用。

以上总结一下就是:BIO卡着,NIO轮询,AIO是自动触发。但都不常用

NIO、AIO linux系统上底层是都是epoll,epoll本身就是轮询,只不过AIO把它封装了一下。所以在linux系统上,NIO效率比AIO效率高,这也是netty对NIO封装的原因

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

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/153420.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!