io程序员java知识点

浅谈“阻塞同步”,“BIO、NIO、AIO”

2017-09-04  本文已影响210人  叫我宫城大人

一、阻塞?同步?

可能大家平常会经常听到这两个名词,但是没花太多心思详细了解,今天就来揭开这层面纱。

一次IO操作,以read方法举例,会经历两个阶段:
(1)等待数据准备(Waitingfor the data to be ready)
是否阻塞指的就是这一个阶段。

(2)将数据从内核拷贝到进程中(Copying the data from the kernel to the process)
是否同步指的就是这一个阶段。

二、BIO

即blocking IO,阻塞式IO,大家最为熟悉的IO流,经常用于操作网络请求,文件读写之类。按读取类型可分为两大类:字符流,字节流。详情图如下:

IO流详情图

附上普通I/O(BIO)的读流程图示:

BIO阻塞同步图

当左边的应用进程发出了“system call”命令后,kernel首先进入第一阶段“wait for data”,然后再进入第二阶段“copying the data”,最后“return OK”返回到用户进程中,即BIO在两个阶段都是阻塞block的,阻塞并同步。

三、NIO

即non-blocking IO,也叫做new IO,因为是NIO是JDK 1.4的java.nio.*包中引入的新I/O库,目的是提高速度,也是对之前的BIO一个补充完善。

NIO的三个重点,重中之重的是:

1. channel(通道)

连接data数据与buffer缓存区的桥梁。

2. Buffer(缓冲区)

用于和NIO通道进行交互。如图所示,数据是从通道读入缓冲区,从缓冲区写入到通道中的。

buffer

3. Selector(选择器)

是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件,如此一个单独的线程可以管理多个channel,从而管理多个连接。

selector

由于selector的原因,可以将NIO简单区分为两种:普通的NIO,和多路复用的NIO(加入了selector管理)。通过下面两张IO操作图示简单说明下两者区别:

NIO非阻塞同步图

很明显的可以观测到NIO在IO操作的准备数据阶段时有一个轮询操作,会不停地发出“system call”到kernel轮询数据是否准备好,没准备好,应用进程可以处理其他事,准备好了之后在发出一个“system call”到kernel进行第二个阶段复制数据,这个过程是blocking的,所以NIO的特点就是在IO执行的第一阶段不会阻塞,但是在第二阶段将数据从内核拷贝到进程这个真是的IO操作还是会阻塞

NIO多路复用图

多路复用的NIO则是上述的普通NIO的补充,在并发量过大的情况下,不可能每个线程都要轮询自己的IO状态,这时就可以使用selector管理所有的IO通道channel,之用开启一个线程,便可解决成千上万的高并发问题(。◕ˇ∀ˇ◕)。

四、AIO

NIO 2.0引入了新的异步通道的概念,并提供了对异步文件通道和异步套接字通道的实现。(基于NIO)
Asynchronous IO,字面意思即异步的IO,完全不阻塞,那我们看看这个的read操作图示:

NIO非阻塞异步图

通过图示可以很清楚得发现,如果是AIO发起read操作之后,kernel收到请求后会立即响应应用进程application,所以应用进程完全可以做其他的事,不会造成任何的block。待kernel第一、二阶段都已经完成之后,会给应用进程发送一个signal,告诉它read操作已经完成。所以AIO的特点是在IO的两个阶段都不会发生阻塞,而是全权交给系统内核才完成,内核完成后通过信号告知应用进程即可

五、各种I/O对比

属性\模型 阻塞BIO 非阻塞NIO 异步AIO
blocking 阻塞并同步 非阻塞但同步 非阻塞并异步
线程数(server:client) 1:1 1:N 0:N
复杂度 简单 较复杂 复杂
吞吐量

具体使用得依据业务的实际应用场景和性能需求而定,如果客户端很少,并发量不大,那么完全可以选择BIO,不过得加入线程池管理;相反要求并发较高的话,就应该采用NIO框架了。

六、简单总结

BIO、NIO、AIO概念认知:

BIO、NIO、AIO适用场景分析:

上一篇下一篇

猜你喜欢

热点阅读