Java BIO/NIO/AIO简单总结

阻塞和非阻塞

阻塞和非阻塞是进程在访问数据的时候,进程需不需要等待底层操作系统的IO操作

阻塞

比如现在我们的程序想要通过网络读取数据,如果是阻塞IO模式,一旦发起请求到操作系统内核去从网络中读取数据,就会阻塞在那里,必须要等待网络中的数据到达了之后,才能从网络读取数据到内核,再从内核返回给程序,如下图

非阻塞

指的就是程序发送请求给内核要从网络读取数据,但是此时网络中的数据还没到,此时不会阻塞住,内核会返回一个异常消息给程序。

程序就可以干点儿别的,然后过一会儿再来发起一次请求给内核,让内核尝试从网络读取数据

因为如果网络中的数据还没到位,是不会阻塞住程序的,需要程序自己不断的轮询内核去尝试读取数据,所以这种IO就是非阻塞的。如下图

 

同步和异步

同步:是指发出一个请求,在没有得到结果之前该请求就不返回结果,请求返回时,也就得到结果了

比如说调用者去调用一个接口,这个接口要进行一系列的算法及数据处理,调用者必须要等待这个接口执行完毕了,调用者才能往下走处理下一步任务。

异步:是指发出一个请求后,立刻得到了回应,但没有返回结果

调用者调用接口之后,直接就返回了,不需要等待接口执行完内部的一系列的算法及数据处理。这种方式需要我们通过状态主动查看是否有了结果, 或者可以设置一个回调来通知调用者。

比如在java里的@Async注解就是将接口变成异步。

同步/异步与阻塞/非阻塞区别

“同步/异步”更多的是针对比如接口调用,服务调用,API类库调用,类似这样的场景。

而“阻塞/非阻塞”概念针对的是底层IO操作的场景,比如磁盘IO,网络IO。但是在Java IO模型里,两种概念之间是有一定的关联关系的 。

同步阻塞BIO------同步在IO操作上(read(),write())

在JDK 1.4之前,主要就是同步阻塞IO模型,在Java里叫做BIO。

在Java代码里调用IO相关接口,发起IO操作之后,Java程序就会同步等待,这个同步指的是Java程序调用IO的API接口的层面而言。

而IO的API在底层的IO操作是基于阻塞IO来的,向操作系统内核发起IO请求,系统内核会等待数据就位之后,才会执行IO操作,执行完毕了才会返回。

同步非阻塞NIO------同步在select()上

JDK 1.4之后的同步非阻塞NIO

在JDK 1.4之后提供了NIO,他的概念是同步非阻塞,也就是说如果你调用NIO接口去执行IO操作,其实还是同步等待的,但是在底层的IO操作上 ,会对系统内核发起非阻塞IO请求,以非阻塞的形式来执行IO。

也就是说,如果底层数据没到位,那么内核返回异常信息,不会阻塞住,但是NIO接口内部会采用非阻塞方式过一会儿再次调用内核发起IO请求,直到成功为止。

但是之所以说是同步非阻塞,这里的“同步”指的就是因为在你的Java代码调用NIO接口层面是同步的(如select()方法),你还是要同步等待底层IO操作真正完成了才可以返回,只不过在执行底层IO的时候采用了非阻塞的方式来执行罢了。

select函数在底层操作系统会通过非阻塞的方式轮询各个Socket,任何一个Socket如果没有数据到达,那么非阻塞的特性会立即返回一个信息。

然后select函数可以轮询下一个Socket,不会阻塞在某个Socket上,所以底层是基于这种非阻塞的模式来“监视”各个Socket谁有数据到达的。

这就是所谓的“同步非阻塞”,但是因为操作系统把上述工作都封装在一个select函数调用里了,可以对多路Socket连接同时进行监视,所以就把这种模型称之为“IO多路复用”模型

通过这种IO多路复用的模型,就可以用一个线程,调用一个select函数,然后监视大量的客户端连接了

异步非阻塞AIO

是JDK 1.7之后,又支持了AIO,也叫做NIO 2.0,他就支持异步IO模型了。

参考 重点推荐十分钟了解BIO、NIO、AIO

        java的IO模型

发布了225 篇原创文章 · 获赞 136 · 访问量 137万+

猜你喜欢

转载自blog.csdn.net/ystyaoshengting/article/details/104181931