今天我们来聊Java IO模型,BIO、NIO、AIO三种常见IO模型

一、写在开头

很久没更新喽,最近build哥一直在忙着工作,忙着写小说,都忘记学习自己的本职了,哈哈,不过现在正式回归!

我们继续学习Java的IO相关内容,之前我们了解到,所谓的IO(Input/Output)就是计算机系统与外部设备之间通信的过程。

二、IO调用过程

接下来我们从应用调用的过程中来分析一下整个IO的执行过程。不过在此之前,我们需要简单的了解一下整个操作系统的空间布局。为了保证操作系统的稳定性和安全性,一个进程的地址空间划分为用户空间(User space) 和 内核空间(Kernel space ) 。

内核空间: 是操作系统内核所使用的空间,用来存储底层内核代码、数据结构以及内核级别的系统调用。内核空间拥有比较高的权限,比如文件管理、进程通信、内存管理等等。
用户空间: 用户级别的应用程序和服务分配的内存区域。它包含了应用程序的代码、数据和运行时堆栈。用户空间与内核空间相对隔离,具有较低的权限级别,不能直接访问内核空间或硬件资源。

所以说,我们想要进行 IO 操作,一定是要依赖内核空间的能力。平常开发过程中接触最多的就是磁盘 IO(读写文件) 和 网络 IO(网络请求和响应)。

执行步骤:

  1. 应用程序发起IO请求;
  2. 系统内核接受到系统调用请求;
  3. 内核等待数据准备;
  4. 内核将数据从内核空间拷贝到用户空间;
  5. IO输出给应用程序。

三、IO常用模型

在UNIX系统中,我们所提到的IO模型一般是这四种:同步阻塞 I/O、同步非阻塞 I/O、I/O 多路复用、信号驱动 I/O 和异步 I/O

不过,在日常使用中,我们常用的多为 BIO(Blocking I/O):同步阻塞 IO 模型、NIO (Non-blocking/New I/O):同步非阻塞 IO 模型、AIO (Asynchronous I/O):异步 IO 模型。

3.1 BIO (Blocking I/O)

在传统的IO中,多以这种同步阻塞的IO模型为主,这种模型下,程序发起IO请求后,处理线程处于阻塞状态,直到请求的IO数据从内核空间拷贝到用户空间。如下图可以直观的体现整个流程(图源:沉默王二)。

如果发起IO的应用程序并发量不高的情况下,这种模型是没问题的。但很明显,当前的互联网中,很多应用都有高并发IO请求的情况,这时就迫切的需要一款高效的IO模型啦。

3.2 NIO (Non-blocking/New I/O)

这种NIO模型,这个N既可以命名为NEW代表一种新型的IO模型,又可以理解为Non-Blocking,非阻塞之意。

Java NIO 是 Java 1.4 版本引入的,基于通道(Channel)和缓冲区(Buffer)进行操作,采用非阻塞式 IO 操作,允许线程在等待 IO 时执行其他任务。常见的 NIO 类有 ByteBuffer、FileChannel、SocketChannel、ServerSocketChannel 等。(图源:深入拆解Tomcat & Jetty)

虽然在应用发起IO请求时,之多多次发起,无须阻塞。但在内核将数据拷贝到用户空间时,还是会阻塞的,为了保证数据的准确性和系统的安全稳定。

3.3 I/O 多路复用模型

在同步非阻塞IO模型下,需要通过不断的轮询去检查请求数据是否已经完成,这个过程是很耗CPU的。因此,便又诞生了I/O多路复用模型。

I/O 多路复用模型 :使用操作系统提供的多路复用功能(如 select、poll、epoll 等),使得单个线程可以同时处理多个 I/O 事件。当某个连接上的数据准备好时,操作系统会通知应用程序。这样,应用程序可以在一个线程中处理多个并发连接,而不需要为每个连接创建一个线程。(图源:沉默王二)

3.4 AIO (Asynchronous I/O)

AIO 也就是 NIO 2。Java 7 中引入了 NIO 的改进版 NIO 2,它是异步 IO 模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

总结

以上BIO、NIO、AIO三种常见的IO模型是Java面试中最常考的,大家一定要记住其各自的特点和作用。

  • 阻塞 I/O:应用程序执行 I/O 操作时,会一直等待数据传输完成,期间无法执行其他任务。
  • 非阻塞 I/O:应用程序执行 I/O 操作时,如果数据未准备好,立即返回错误状态,不等待数据传输完成,可执行其他任务。
  • 异步 I/O:应用程序发起 I/O 操作后,内核负责数据传输过程,完成后通知应用程序。应用程序无需等待数据传输,可执行其他任务。

结尾彩蛋

如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏呀。原创不易,转载请联系Build哥!

如果您想与Build哥的关系更近一步,还可以关注"JavaBuild888",在这里除了看到《Java成长计划》系列博文,还有提升工作效率的小笔记、读书心得、大厂面经、人生感悟等等,欢迎您的加入!

相关推荐
武子康1 分钟前
大数据-78 Kafka 集群模式 集群的应用场景与Kafka集群的搭建 三台云服务器
java·大数据·服务器·分布式·架构·kafka
2的n次方_2 分钟前
深入探秘 Java 网络编程:从基础到多线程服务器的全方位指南
java·服务器·网络
爱吃糖的蠢猫8 分钟前
awk详解
linux·服务器·开发语言·chrome·bash
让开,我要吃人了1 小时前
HarmonyOS开发实战( Beta5版)应用滑动场景帧率问题分析最佳实践
linux·开发语言·华为·性能优化·移动开发·harmonyos·鸿蒙
嘻嘻嘻Mr.Huang1 小时前
QT实现简易文件夹
开发语言·qt
Mueisya1 小时前
C++初学(18)
开发语言·c++
北欧人写代码1 小时前
SpringBoot 多环境日志配置
java·spring boot·后端
azhou的代码园2 小时前
基于Java+SpringBoot+Vue的汽车销售网站
java·vue.js·spring boot·毕业设计·汽车销售网站
樱花开的那年2 小时前
【C++】将myString类中能够实现的操作都实现一遍
开发语言·c++
Nonullpoint.2 小时前
《深入理解 Java 中的适配器模式》
java·python·适配器模式