BIO、NIO、AIO区别

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

1、工作原理图

BIO、NIO、AIO区别_第1张图片

2、java代码

2.1、服务端代码:

BIO、NIO、AIO区别_第2张图片

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

2.2、客户端代码

BIO、NIO、AIO区别_第3张图片

3、BIO阻塞的原因

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

4、使用场景:

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

二、NIO:

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

1.1、工作原理图

BIO、NIO、AIO区别_第4张图片

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

1.2、java代码

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

BIO、NIO、AIO区别_第6张图片
BIO、NIO、AIO区别_第7张图片
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、工作原理图

BIO、NIO、AIO区别_第8张图片
selector干两件事:一是每隔一段时间看看有没有新的客户端要连上来,如果有则把客户端连到服务器。二是当连接完的客户端要读写时,把这些读写操作交给线程池去干(这样就不再是单线程了)

三、AIO:异步IO

工作原理图

BIO、NIO、AIO区别_第9张图片
有客户端要连的时候操作系统通知回调函数,然后回调函数去处理;当有读写操作的时候,继续调跟读写有关的回调函数。但是依然有ByteBuffer,所以不太常用

四、三者比较

1、BIO(同步阻塞IO):

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

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

都是selector每隔一段时间去轮询看看有没有要处理的连接操作或读写操作(单线程selector自己处理读写操作、多线程selector把读写操作给线程池)。但是ByteBuffer变态,所以不太常用
BIO、NIO、AIO区别_第10张图片

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

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

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

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

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

你可能感兴趣的:(网络,nio,java,bio,aio)