当前位置: 首页 > article >正文

通过操作系统中的IO模型理解Java中的BIO,NIO,AIO

操作系统中的三种IO模型

阻塞I/O

先来看看阻塞 I/O,当用户程序执行 read,线程会被阻塞

一直等到内核数据准备好,并把数据从内核缓冲区拷贝到应用程序的缓冲区中,当拷贝过程完成,read 才会返回

注意:阻塞等待的是「内核数据准备好」和「数据从内核态拷贝到用户态」这两个过程

过程如下图:

非阻塞 I/O

知道了阻塞 I/O,来看看非阻塞 I/O,非阻塞的 read 请求在数据未准备好的情况下立即返回,可以继续下执行

此时应用程序不断轮询内核直到数据准备好

内核将数据拷贝到应用程序缓冲区,read 才可以获取到结果

过程如下图:

注意,这里最后一次 read 调用,获取数据的过程,是一个同步的过程,是需要等待的过程。这里的同步指的是内核态的数据拷贝到用户程序的缓存区这个过程


异步IO

举个例子,如果 socket 设置了 O_NONBLOCK 标志,那么就表示使用的是非阻塞 I/O 的方式访问,而不做任何设置的话,默认是阻塞 I/O。

因此,无论 read 和 send 是阻塞 I/O,还是非阻塞 I/O 都是同步调用

因为在 read 调用时,内核将数据从内核空间拷贝到用户空间的过程都是需要等待的,也就是说这个过程是同步的,如果内核实现的拷贝效率不高,read 调用就会在这个同步过程中等待比较长的时间.


真正的异步 I/O 是「内核数据准备好」和「数据从内核态拷贝到用户态」这两个过程都不用等待

当我们发起 aio_read(异步 I/O)之后,就立即返回,内核自动将数据从内核空间拷贝到用户空间

这个拷贝过程同样是异步的,内核自动完成的

和前面的同步操作不一样,应用程序并不需要主动发起拷贝动作

过程如下图:


理解IO的简单例子

举个你去饭堂吃饭的例子,你好比应用程序,饭堂好比操作系统

阻塞 I/O

你去饭堂吃饭,但是饭堂的菜还没做好,然后你就一直在那里等啊等,等了好长一段时间终于等到饭堂阿姨把菜端了出来(数据准备的过程),但是你还得继续等阿姨把菜(内核空间)打到你的饭盒里(用户空间),经历完这两个过程,你才可以离开。

非阻塞 I/O

你去了饭堂,问阿姨菜做好了没有,阿姨告诉你没,你就离开了,过几十分钟,你又来饭堂问阿姨,阿姨说做好了,于是阿姨帮你把菜打到你的饭盒里,这个过程你是得等待的


 

异步 I/O

你让饭堂阿姨将菜做好并把菜打到饭盒里后,把饭盒送到你面前,整个过程你都不需要任何等待。


很明显,异步 I/O 比同步 I/O 性能更好,因为异步 I/O 在「内核数据准备好」和「数据从内核空间拷贝到用户空间」这两个过程都不用等待。


BIO AIO NIO有什么区别

什么是IO

IO(Input/Output)是指输入/输出,用于描述计算机与外部设备(如文件、网络、键盘、显示器等)之间的数据交换过程。

计算机在运行过程中,需要与外部世界进行数据的输入和输出。例如,从文件中读取数据、将数据写入到网络传输中、从键盘接收用户的输入等都属于 IO 操作。

需要 IO 的主要原因是:

  1. 数据持久化:将数据从内存写入到磁盘或其他存储介质中,实现数据的持久化和长期存储。
  2. 数据交互:与外部设备进行数据的输入和输出,在计算机与用户、计算机与计算机之间传输数据。
  3. 程序与外部设备的交互:程序需要和外部设备(如键盘、鼠标、显示器、网络等)进行交互,接收用户输入,展示输出结果。

IO 操作是计算机系统中的重要组成部分,它通过数据的输入和输出实现了与外部设备的交互和数据的持久化。在计算机软件开发和系统运行中,IO 是不可或缺的一部分


三个IO有什么区别

简单来说,BIO 就是传统 IO 包,它诞生的最早,但它是同步、阻塞的;

所以在 JDK 1.4 又有了 NIO, NIO 是对 BIO 的改进提供了多路复用的同步非阻塞 IO,而 AIO 是 NIO 的升级,提供了异步非阻塞 IO。

它们的具体区别如下:

  • BIO(Blocking I/O):同步阻塞 IO,传统的 java.io 包,它是基于流模型实现的,交互的方式是同步阻塞方式,也就是说在读入输入流或者输出流时,在读写动作完成之前线程会一直阻塞在那里, 它们之间的调用是可靠的线性顺序。它的优点是代码比较简单、直观;缺点是 IO 的效率和扩展性很低,容易成为应用性能瓶颈。
  • NIO(Non-blocking I/O):同步非阻塞 IO,Java 1.4 引入的 java.nio 包,提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层高性能的数据操作方式。
  • AIO(Asynchronous I/O):异步非阻塞 IO,Java 1.7 之后引入的包,是 NIO 的升级版本,异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

所以,简单来说:BIO 是同步阻塞 IO;NIO 是同步非阻塞 IO;AIO 是异步非阻塞 IO


关键总结

BIO:每个连接对应一个线程,调用read()时线程被阻塞,直到数据就绪

NIO:基于多路复用(Selector)实现,通道(Channel)设置为非阻塞模式。单线程通过轮询Selector理多个连接的IO事件

AIO:使用回调或Future机制,IO操作完成后自动触发回调函数

模型

Java实现

操作系统对应机制

核心特点

同步阻塞

BIO(每个连接一个线程)

read()

阻塞调用

简单但资源消耗大

同步非阻塞

NIO(Selector多路复用)

epoll

/kqueue

多路复用

单线程处理多连接,减少线程开销

异步非阻塞

AIO(回调机制)

IOCP

(Windows)、io_uring

(Linux)

真正的异步IO,无需用户态轮询


http://www.kler.cn/a/548903.html

相关文章:

  • Python入门全攻略(六)
  • 小米 R3G 路由器(Pandavan)实现网络打印机功能
  • 在conda环境下,安装Pytorch和CUDA
  • 【第11章:生成式AI与创意应用—11.4 生成式AI在其他领域的创新应用与未来展望】
  • 基于阿里云可观测产品构建企业级告警体系的通用路径与最佳实践
  • 深入解析 vLLM:高性能 LLM 服务框架的架构之美(上)
  • React Hooks 的两个坑点
  • 【第15章:量子深度学习与未来趋势—15.1 量子计算基础与量子机器学习的发展背景】
  • 基于Spring Boot的大学校园生活信息平台的设计与实现(LW+源码+讲解)
  • C# 变量,字段和属性的区别
  • Web后端 - Maven管理工具
  • 【第10章:自然语言处理高级应用—10.4 NLP领域的前沿技术与未来趋势】
  • 【C++】34.智能指针(1)
  • STM32 如何使用DMA和获取ADC
  • PerfMonitor高效处理器性能监控与分析利器
  • 374_C++_升级等其他类型标签,使用将4字节字符串转换为无符号整数的定义方式
  • 免费好用的DeepSeek平台汇总(持续更新...)
  • 动态库与静态库:深入解析与应用
  • python的两种单例模式
  • STM32H743ZIT6 FreeRTOS CMSIS_V2 Lwip DP83848/LAN8720 最新HAL V1.12.1版本 AC6编译器,速通。