Java IO 模型常⻅⾯试题总结
16 ⼈点赞
上⼀篇
如何统计⽹站UV?
下⼀篇
Java 数据类型常⻅⾯试题总结
所有评论(7)
引⽤原⽂:如何完成⼀次 IO:https://llc687.top/post/如何完成⼀次-io/
注册 或 登录 语雀进⾏评论
加⼊语雀,参与知识分享与交流
或 语雀进⾏评论
%
关于语雀 使⽤帮助 数据安全 服务协议 English 快速注册
⾯试中经常喜欢问的⼀个问题,因为通过这个问题,⾯试官可以顺便了解⼀下你的操作系
统的⽔平。
IO 模型这块确实挺难理解的,需要太多计算机底层知识。写这篇⽂章⽤了挺久,就⾮常
希望能把我所知道的讲出来吧!希望朋友们能有收货!为了写这篇⽂章,还翻看了⼀下
《UNIX ⽹络编程》这本书,太难了,我滴乖乖!⼼痛~
个⼈能⼒有限。如果⽂章有任何需要补充/完善/修改的地⽅,欢迎在评论区指出,共同进
步!
I/O ⼀直是很多⼩伙伴难以理解的⼀个知识点,这篇⽂章我会将我所理解的 I/O 讲给你
听,希望可以对你有所帮助。
I/O(Input/Outpu) 即输⼊/输出 。
我们先从计算机结构的⻆度来解读⼀下 I/O。
根据冯.诺依曼结构,计算机结构分为 5 ⼤部分:运算器、控制器、存储器、输⼊设备、
输出设备。
输⼊设备(⽐如键盘)和输出设备(⽐如显示屏)都属于外部设备。⽹卡、硬盘这种既可
以属于输⼊设备,也可以属于输出设备。
输⼊设备向计算机输⼊数据,输出设备接收计算机输出的数据。
从计算机结构的视⻆来看的话, I/O 描述了计算机系统与外部设备之间通信的过程。
我们再先从应⽤程序的⻆度来解读⼀下 I/O。
根据⼤学⾥学到的操作系统相关的知识:为了保证操作系统的稳定性和安全性,⼀个进程
的地址空间划分为 ⽤户空间(User space) 和 内核空间(Kernel space ) 。
像我们平常运⾏的应⽤程序都是运⾏在⽤户空间,只有内核空间才能进⾏系统态级别的资
源有关的操作,⽐如如⽂件管理、进程通信、内存管理等等。也就是说,我们想要进⾏
IO 操作,⼀定是要依赖内核空间的能⼒。
并且,⽤户空间的程序不能直接访问内核空间。
当想要执⾏ IO 操作时,由于没有执⾏这些操作的权限,只能发起系统调⽤请求操作系统
帮忙完成。
因此,⽤户进程想要执⾏ IO 操作的话,必须通过 系统调⽤ 来间接访问内核空间
我们在平常开发过程中接触最多的就是 磁盘 IO(读写⽂件) 和 ⽹络 IO(⽹络请求和相
应)。
从应⽤程序的视⻆来看的话,我们的应⽤程序对操作系统的内核发起 IO 调⽤(系统调
⽤),操作系统负责的内核执⾏具体的 IO 操作。也就是说,我们的应⽤程序实际上只是
发起了 IO 操作的调⽤⽽已,具体 IO 的执⾏是由操作系统的内核来完成的。
当应⽤程序发起 I/O 调⽤后,会经历两个步骤:
1. 内核等待 I/O 设备准备好数据
2. 内核将数据从内核空间拷⻉到⽤户空间。
UNIX 系统下, IO 模型⼀共有 5 种: 同步阻塞 I/O、同步⾮阻塞 I/O、I/O 多路复⽤、信
号驱动 I/O 和异步 I/O。
这也是我们经常提到的 5 种 IO 模型。
BIO 属于同步阻塞 IO 模型 。
同步阻塞 IO 模型中,应⽤程序发起 read 调⽤后,会⼀直阻塞,直到在内核把数据拷⻉到
⽤户空间。
在客户端连接数量不⾼的情况下,是没问题的。但是,当⾯对⼗万甚⾄百万级连接的时
候,传统的 BIO 模型是⽆能为⼒的。因此,我们需要⼀种更⾼效的 I/O 处理模型来应对更
⾼的并发量。
Java 中的 NIO 于 Java 1.4 中引⼊,对应 java.nio 包,提供了 Channel , Select
or , Buffer 等抽象。NIO 中的 N 可以理解为 Non-blocking,不单纯是 New。它⽀
持⾯向缓冲的,基于通道的 I/O 操作⽅法。 对于⾼负载、⾼并发的(⽹络)应⽤,应使
⽤ NIO 。
Java 中的 NIO 可以看作是 I/O 多路复⽤模型。也有很多⼈认为,Java 中的 NIO 属于同
步⾮阻塞 IO 模型。
跟着我的思路往下看看,相信你会得到答案!
我们先来看看 同步⾮阻塞 IO 模型。
同步⾮阻塞 IO 模型中,应⽤程序会⼀直发起 read 调⽤,等待数据从内核空间拷⻉到⽤户
空间的这段时间⾥,线程依然是阻塞的,直到在内核把数据拷⻉到⽤户空间。
相⽐于同步阻塞 IO 模型,同步⾮阻塞 IO 模型确实有了很⼤改进。通过轮询操作,避免了
⼀直阻塞。
但是,这种 IO 模型同样存在问题:应⽤程序不断进⾏ I/O 系统调⽤轮询数据是否已经准
备好的过程是⼗分消耗 CPU 资源的。
这个时候,I/O 多路复⽤模型 就上场了。
IO 多路复⽤模型中,线程⾸先发起 select 调⽤,询问内核数据是否准备就绪,等内核把
数据准备好了,⽤户线程再发起 read 调⽤。read 调⽤的过程(数据从内核空间->⽤户空
间)还是阻塞的。
IO 多路复⽤模型,通过减少⽆效的系统调⽤,减少了对 CPU 资源的消耗。
Java 中的 NIO ,有⼀个⾮常重要的选择器 ( Selector ) 的概念,也可以被称为 多路复⽤
器。通过它,只需要⼀个线程便可以管理多个客户端连接。当客户端数据到了之后,才会
为其服务。
AIO 也就是 NIO 2。Java 7 中引⼊了 NIO 的改进版 NIO 2,它是异步 IO 模型。
异步 IO 是基于事件和回调机制实现的,也就是应⽤操作之后会直接返回,不会堵塞在那
⾥,当后台处理完成,操作系统会通知相应的线程进⾏后续的操作。
⽬前来说 AIO 的应⽤还不是很⼴泛。Netty 之前也尝试使⽤过 AIO,不过⼜放弃了。这是
因为,Netty 使⽤了 AIO 之后,在 Linux 系统上的性能并没有多少提升。
最后,来⼀张图,简单总结⼀下 Java 中的 BIO、NIO、AIO。
《深⼊拆解 Tomcat & Jetty》
如何完成⼀次 IO:https://llc687.top/post/如何完成⼀次-io/
程序员应该这样理解 IO:https://www.jianshu.com/p/fa7bdc4f3de7
10 分钟看懂, Java NIO 底层原理:
https://www.cnblogs.com/crazymakercircle/p/10225159.html
IO 模型知多少 | 理论篇:https://www.cnblogs.com/sheng-jie/p/how-much-
you-know-about-io-models.html
《UNIX ⽹络编程 卷 1;套接字联⽹ API 》6.2 节 IO 模型
前⾔
I/O
何为 I/O?
有哪些常⻅的 IO 模型?
Java 中 3 种常⻅ IO 模型
BIO (Blocking I/O)
NIO (Non-blocking/New I/O)
⽬前⽀持 IO 多路复⽤的系统调⽤,有 select,epoll 等等。select 系统调⽤,是⽬前⼏
乎在所有的操作系统上都有⽀持
:内核提供的系统调⽤,它⽀持⼀次查询多个系统调⽤的可⽤状态。⼏
乎所有的操作系统都⽀持。
:linux 2.6 内核,属于 select 调⽤的增强版本,优化了 IO 的执⾏效
率。
AIO (Asynchronous I/O)
参考
●
●
●
●
●
●
原作者修改了⽂章链接:https://llc687.top/126.html
嗯嗯 这篇⽂章主要介绍Java 中 3 种常⻅的 IO 模型。
⼤纲
NIO (Non-blocking/New I/O)
16
7
登录 / 注册