本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
这是一个面试中经常被问到的问题,也是高频面试题。我本来是不想写这方面的内容的,怕误导大家。但是奈何总有网友给我私信,想让我简单的解释一下。
所以,就有了本文。其中可能有部分描述不准确或者错误的地方,大家留言,共同交流,共同进步!
BIO,NIO,AIO 这三个名词中都带了一个“IO”。那我们就先看看什么是“IO”。
IO
IO 其实就是 INPUT 和 OUPUT 的简称。与 IO 相关的还有“IO流”,就是说以流的形式进行“IO”。还有就是“IO读写”,很多老司机都搞不清什么是 INPUT 和 OUPUT。
这个 INPUT 和 OUPUT 其实很简单,以内存为目标,数据进内存叫 In,出内存叫 Out。以前我的老师都经常搞错!
明白 IO 后,我们在看来 BIO。
BIO
即 Blocking IO,阻塞式 IO。也有人称它为同步阻塞 IO,为什么加了个同步呢?我下面会讲。
阻塞 IO,说白了就是数据的读取写入必须阻塞在一个线程内等待其完成。
为什么也称为同步阻塞 IO 呢?因为操作 IO 有两个阶段,一个内核,一个是用户空间。
所谓同步阻塞 IO,就是说,这两个阶段都被阻塞了。比如,一个 UDP 数据包,在网络传输过程中或数据包还不完整时,kernel 就会被阻塞,等待足够的数据到来。也就是说数据被拷贝到操作系统内核的缓冲区中是需要一个过程的。而在用户进程这边,整个进程会被阻塞。当 kernel 一直等到数据准备好了,它就会将数据从 kernel 中拷贝到用户内存,然后 kernel 返回结果,用户进程才解除 block 的状态,重新运行起来。
还搞不懂,就看下面这个图,画的其实不是很好。
这里面有两个 block,所以,有人把 BIO 称为同步阻塞 IO,是没错的。同步和异步你可以看作是针对应用程序和内核的交互而言的就行了。
NIO
NIO,nonblocking IO,也叫做 new IO,因为是 NIO 是 JDK 1.4 的 java.nio.* 包中引入的新 I/O 库,目的是提高速度,也是对之前的 BIO 一个补充完善。
在 BIO 模型中,这种 IO 效率太低了,如果需要并发处理多个 I/O 请求,那就需要多线程来支持。我不可能开无限个线程吧,线程开的越多 CPU 切换就成了问题。
所以,人们想到了一种新的实现,New IO。NIO 使用了多路复用器机制,以 socket 使用来说,多路复用器通过不断轮询各个连接的状态,只有在 socket 有流可读或者可写时,应用程序才需要去处理它,在线程的使用上,就不需要一个连接就必须使用一个处理线程了,而是只是有效请求时(确实需要进行 I/O 处理时),才会使用一个线程去处理,这样就避免了 BIO 模型下大量线程处于阻塞等待状态的情景。
何谓多路复用?你可以这样理解,就是多条线路上的请求,我们只用一个或者少量的线程来检查各路请求的连接状态,只有在某条线路上有可读或可写的数据时,在开线程去处理。
这样做了之后,效率确实提升了不少。但是还不完美,所以就有了 AIO。
AIO
AIO 就是 Asynchronous I/O,异步非阻塞 I/O。Java AIO 就是 Java 作为对异步 IO 提供支持的 NIO2,Java NIO2 (JSR 203)定义了更多的 New I/O APIs,NIO2 在 2003 年被提出,直到 2011 年才发布, 最终在 JDK 7 中才实现。
AIO 相对于 NIO 的区别在于,NIO 需要使用者线程不停的轮询 IO 对象,来确定是否有数据准备好可以读了,而 AIO 则是在数据准备好之后,才会通知数据使用者,这样使用者就不需要不停地轮询了。当然 AIO 的异步特性并不是 Java 实现的伪异步,而是使用了系统底层 API 的支持,在 Linux/Unix 系统下,采用了 epoll IO 模型,而 windows 系统下则是使用了 IOCP 模型。
区别与对比
BIO、NIO、AIO 三者之间的区别与联系,如下图所示:
关于 IO 模型划分,不是本文的关注点。大家可以多看看《Unix网络编程》这本书。
最后,解释几个名词。
- 同步:指的是用户进程触发 I O操作并等待或者轮询的去查看 IO 操作是否就绪
- 异步:异步是指用户进程触发 IO 操作以后便开始做自己的事情,而当 IO 操作已经完成的时候会得到 IO 完成的通知(异步的特点就是通知)
- 阻塞:所谓阻塞方式的意思是指,当试图对该文件描述符进行读写时,如果当时没有东西可读,或者暂时不可写,程序就进入等待状态,直到有东西可读或者可写为止
- 非阻塞:非阻塞状态下,如果没有东西可读,或者不可写,读写函数马上返回,而不会等待
参考资料
- Understanding of BIO, NIO, and AIO in Java
- BIO/NIO/AIO
- Java BIO、NIO、AIO
- Java NIO、BIO、 AIO 与 同步、阻塞、非阻塞、异步IO 简析
- Java NIO浅析
最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » 拜托,请别再问我 BIO,NIO,AIO 了!