JAVA成长日记之聊聊AIO,BIO,NIO

2021/5/9 20:31:46

本文主要是介绍JAVA成长日记之聊聊AIO,BIO,NIO,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

基础概念

同步异步

阻塞非阻塞

总结

IO模型

同步阻塞(blocking-IO)简称BIO

缺点

适用场景

同步非阻塞(non-blocking-IO)简称NIO

优点

缺点

适用场景

异步非阻塞(synchronous-non-blocking-IO)简称AIO

优点

缺点

适用场景

举例


 

在JAVA面试中经常会问到 IO 相关的问题。那么 IO 到底是什么的,AIO,BIO,NIO又分别是什么呢。

面试中为何都问到IO,小会议室里为何气氛尴尬?这一切究竟是人性的扭曲,还是道德的沦丧?让我们一起走近IO,探寻真相。(OS:走进科学)

 

首先我们需要了解一下IO这个概念。顾名思义 IO 其实就是Input/Output的缩写,也就是输入和输出。

 

基础概念

在开始了解 IO 之前我们需要了解一些概念 和 IO模型 , 会更有助于我们了解IO

同步异步

同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)。

同步 就是在发起调用之后,一直等待直到获取到返回值。

异步 则是在请求发起之后,调用就直接返回了,并没有返回结果。 其实可以理解为调用者不会立刻得到结果,而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

 

举个通俗的例子吧:

同步: 你去麦当劳买汉堡,通过人工点餐之后,店长把汉堡给你然后你离开了。

异步: 你去麦当劳买汉堡,通过人工点餐之后你就离开了,然后麦当劳通过短信或者微信通知的方式告诉你汉堡做好了,你再过来取。

 

阻塞非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态。

阻塞:再调用结果返回前,当前线程会被挂起。调用线程只有在得到结果之后返回。

非阻塞:调用在不能马上得到结果之前,该调用不会则色当前线程。

 

通俗的例子:

阻塞: 你去汉堡王买汉堡,通过人工点餐之后一直在柜台前等待,之后拿到汉堡再走。

非阻塞: 你去汉堡王买汉堡,通过人工点餐之后就自顾自走了,然后每隔一段时间来确认一下汉堡是否做好了。

 

总结

读完上述解释之后,肯定还是懵逼状态中的。感觉同步异步,阻塞非阻塞好像差不多亚子。

其实不然:

同步与异步是对应于调用者与被调用者,它们是线程之间的关系。

两个线程之间要么是同步的,要么是异步的 。

同步操作时,调用者需要等待被调用者返回结果,才会进行下一步操作。而异步则相反,调用者不需要等待被调用者返回调用,即可进行下一步操作,被调用者通常依靠事件、回调等机制来通知调用者结果。

 

阻塞与非阻塞是对同一个线程来说的

在某个时刻,线程要么处于阻塞,要么处于非阻塞。

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态: 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

 

到这里大家应该就对同步异步,阻塞非阻塞的有一定的了解了。那么让我们开始对IO模型的了解。

 

IO模型

同步阻塞(blocking-IO)简称BIO

BIO全称是Blocking IO,是JDK1.4之前的传统IO模型。

发送方发送请求之后一直等待响应。 接收方处理请求时进行的IO操作如果不能马上等到返回结果,就一直等到返回结果后,才响应发送方,期间不能进行其他工作。

数据的读取写入必须阻塞在一个线程内等待其完成。

 

缺点

        每一个连接都需要单独创建线程。所以在并发大的时候,系统需要创建大连更多资源去处理连接。

        连接建立后,如果客户端的线程没有数据可读时,线程则会阻塞至有数据后才读取,造成线程资源的浪费

适用场景

        连接数少、多资源(多IO操作)的长连接。

 

同步非阻塞(non-blocking-IO)简称NIO

NIO一般常见于 Reactor 响应式编程。 NIO即 线程发起IO请求后,立即返回(非阻塞io)。同步指的是必须等待IO缓冲区内的数据就绪,而非阻塞指的是,用户线程不原地等待IO缓冲区,可以先做一些其他操作,但是要定时轮询检查IO缓冲区数据是否就绪。

JAVA在JDK1.4版本中加入nio的功能,所有涉及类都在java.nio包下。Java中的NIO 是new IO的意思。其实是NIO加上IO多路复用技术。普通的NIO是线程轮询查看一个IO缓冲区是否就绪,而Java中的new IO指的是线程轮询地去查看一堆IO缓冲区中哪些就绪,这是一种IO多路复用的思想。IO多路复用模型中,将检查IO数据是否就绪的任务,交给系统级别的select或epoll模型,由系统进行监控,减轻用户线程负担。

NIO主要有buffer、channel、selector三种技术的整合,通过零拷贝的buffer取得数据,每一个客户端通过channel在selector(多路复用器)上进行注册。服务端不断轮询channel来获取客户端的信息。channel上有connect,accept(阻塞)、read(可读)、write(可写)四种状态标识。根据标识来进行后续操作。所以一个服务端可接收无限多的channel。不需要新开一个线程。大大提升了性能。

 

优点

        并发性高

缺点

        不适合重量级数据的操作

适用场景

        聊天室等仅轻量级数据传输的场景

 

OS:JAVA中的NIO其实可讲的内容十分多,下次有机会会详细讲解一下,这次只是先了解一下概念。预设NIO传送门

 

异步非阻塞(synchronous-non-blocking-IO)简称AIO

AIO是真正意义上的异步非阻塞IO模型。 上述NIO实现中,需要用户线程定时轮询,去检查IO缓冲区数据是否就绪,占用应用程序线程资源,其实轮询相当于还是阻塞的,并非真正解放当前线程,因为它还是需要去查询哪些IO就绪。而真正的理想的异步非阻塞IO应该让内核系统完成,用户线程只需要告诉内核,当缓冲区就绪后,通知我或者执行我交给你的回调函数。

AIO可以做到真正的异步的操作,但实现起来比较复杂,支持纯异步IO的操作系统非常少,目前也就windows是IOCP技术实现了,而在Linux上,底层还是是使用的epoll实现的。

 

优点

        并发性高、CPU利用率高、线程利用率高

缺点

        不适合轻量级数据传输,因为进程之间频繁的通信在追错、管理和资源消耗上不是很可观。

适用场景

        对并发有需求的重量级数据传输

 

举例

了解完概念之后,我们举一些生活中的例子吧。

BIO:我去外婆家吃饭,发现要排队,于是取号门口坐等了一小时,然后才开始吃饭。

NIO:我去外婆家吃饭,取了号之后发现妈耶要排好久,所以我决定去逛一下gai,但是每逛一会就跑回来看有没有排到我。所以我又吃到了外婆家也逛到了gai。(NIO)

AIO:我去外婆家吃饭,取了号之后发现妈耶要排好久,但是我发现可以留下电话让店员到我的号之后联系我,所以我放心大胆的去逛gai,直到店员通知我让我回来吃饭。

 

 



这篇关于JAVA成长日记之聊聊AIO,BIO,NIO的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程