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

java,io,bio,nio,aio · 浏览次数 : 85

小编点评

一、前言 大家好,我是负责讲解Java IO系列的沉默王二。上次我们学习了Java IO的基本概念,以及应用调用过程中的IO执行过程。今天我们将继续深入学习Java IO的相关知识,包括IO调用过程、常用模型等方面的内容。 二、IO调用过程 在操作系统中,IO操作是一个复杂的过程,通常涉及多个阶段。下面是一个简化的IO调用过程: 1. 应用程序发起IO请求; 2. 系统内核接收到系统调用请求; 3. 内核等待数据准备; 4. 内核将数据从内核空间拷贝到用户空间; 5. IO输出给应用程序。 这个过程涉及到用户空间和内核空间之间的数据交换,以及操作系统内核对IO请求的处理。在Java中,我们通常使用字节流(Byte Stream)或字符流(Character Stream)来实现IO操作,它们分别对应于字节缓冲区和字符缓冲区。 三、IO常用模型 在Java中,常见的IO模型主要有四种:同步阻塞I/O、同步非阻塞I/O、I/O多路复用和异步I/O。这些模型各有特点和应用场景。 1. 同步阻塞I/O(BIO):在这种模型下,应用程序发起IO请求后,处理线程会一直阻塞,直到请求的IO数据从内核空间拷贝到用户空间。这种模型的优点是简单易懂,但缺点是不适用于高并发场景。 2. 同步非阻塞I/O(NIO):NIO模型采用非阻塞式IO操作,允许线程在等待IO时执行其他任务。当数据准备好时,操作系统会通知应用程序。这种模型的优点是可以提高系统的并发性,但缺点是需要处理线程同步和数据同步的问题。 3. I/O多路复用:I/O多路复用模型使用操作系统提供的多路复用功能(如select、poll、epoll等),使得单个线程可以同时处理多个I/O事件。这种模型的优点是可以大大减少线程的使用,提高系统的吞吐量,但缺点是需要处理事件分发和资源抢占等问题。 4. 异步I/O(AIO):异步I/O模型是基于事件和回调机制实现的,应用程序发起IO操作后,内核负责数据传输过程,完成后通知应用程序。这种模型的优点是可以提高系统的响应速度和并发性,但缺点是需要处理底层的事件处理和回调逻辑。 四、总结 本文简要介绍了Java IO的基础知识、调用过程以及常用模型。通过学习这些知识,我们可以更好地理解Java IO系统的工作原理,并在实际开发中选择合适的IO模型来优化应用程序的性能。

正文

一、写在开头

很久没更新喽,最近build哥一直在忙着工作,忙着写小说,都忘记学习自己的本职了,哈哈,不过现在正式回归!
我们继续学习Java的IO相关内容,之前我们了解到,所谓的IO(Input/Output)就是计算机系统与外部设备之间通信的过程。

二、IO调用过程

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

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

所以说,我们想要进行 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数据从内核空间拷贝到用户空间。如下图可以直观的体现整个流程(图源:沉默王二)。
image

如果发起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)
image

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

3.3 I/O 多路复用模型

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

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

3.4 AIO (Asynchronous I/O)

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

image

总结

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

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

与今天我们来聊Java IO模型,BIO、NIO、AIO三种常见IO模型相似的内容:

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

一、写在开头 很久没更新喽,最近build哥一直在忙着工作,忙着写小说,都忘记学习自己的本职了,哈哈,不过现在正式回归! 我们继续学习Java的IO相关内容,之前我们了解到,所谓的IO(Input/Output)就是计算机系统与外部设备之间通信的过程。 二、IO调用过程 接下来我们从应用调用的过程中

聊一聊 GDB 调试程序时的几个实用命令

一:背景 1. 讲故事 用惯了宇宙第一的 Visual Studio 再用其他的开发工具还是有一点不习惯,不习惯在于想用的命令或者面板找不到,总的来说还是各有千秋吧,今天我们来聊一下几个在调试中比较实用的命令: 查看内存 硬件断点 虚拟内存布局 二:命令解读 1. 查看内存 相信大家都知道 Visu

[转帖]带你重走 TiDB TPS 提升 1000 倍的性能优化之旅

https://tidb.net/blog/29074d86#TiDB%20%E6%80%A7%E8%83%BD%E5%92%8C%E7%A8%B3%E5%AE%9A%E6%80%A7%E7%9A%84%E6%8C%91%E6%88%98 今天我们来聊一下数据库的性能优化,第一部分简单介绍一下性能优

[转帖]浅谈系统稳定性与高可用保障的几种思路

https://segmentfault.com/u/dewujishu 一、前言 高并发、高可用、高性能被称为互联网三高架构,这三者都是工程师和架构师在系统架构设计中必须考虑的因素之一。今天我们就来聊一聊三H中的高可用,也是我们常说的系统稳定性。 本篇文章只聊思路,没有太多的深入细节。阅读全文大概

动图图解 | UDP就一定比TCP快吗?

学习&转载文章:"动图图解 | UDP就一定比TCP快吗?" UDP比TCP快吗? 相信就算不是八股文老手,也会下意识的脱口而出:"是"。 这要追问为什么,估计大家也能说出个大概。 但这也让人好奇,用UDP就一定比用TCP快吗?什么情况下用UDP会比用TCP慢? 我们今天就来聊下这个话题。 使用so

[转帖]国产数据库:五款国产数据,你知道哪款?

https://nic.hnuu.edu.cn/10043/2022/0027132.html 随着互联网的高速发展,目前数据的存储越来越多,传统的数据库逐渐不能满足人们对海量数据、高效查询的需求,国产的数据库如雨后春笋一样,一个个冒了出来来解决我们高速科技发展的数据库瓶颈,今天就给大家聊一聊目前最

架构师日记-如何写的一手好代码

在日常工作中,我经常听到部分同学抱怨代码质量问题,潜台词是:“除了自己的代码,其他人写的都是垃圾,得送到绞刑架上,重构!”。今天就来聊一聊,如何写的一手好代码。

别以为逃离大城市你就能舒适了,小城市可比你想象的内卷!

大家好,我是刘牌,今天聊一下最近的一些经历和感悟还有回到三线城市的感悟,希望对大家有一定的帮助! 欢迎关注我的公众号【刘牌】,一起探讨人生,职业规划,发展副业,一起成长! 一、我不适合躺,也躺不了 我毕业之后就到了成都,去了一家做基础软件的上市公司,不过我们部门还是属于业务部门,差不多干了两年,因为

【动画进阶】类 ChatGpt 多行文本打字效果

今天我们来学习一个有意思的多行文本输入打字效果,像是这样: 这个效果其实本身并非特别困难,实现的方式也很多,在本文中,我们更多的会聚焦于整个多行打字效果最后的动态光标的实现。 也就是如何在文本不断变长,在不确定行数的情况下,让文字的最末行右侧处,一直有一个不断闪烁的光标效果: 单行文本打字效果 在此

#Powerbi 1分钟学会,SUMMARIZE函数,分组汇总并新建表

今天我们来学习一个新的表函数,SUMMARIZE函数是DAX中的一个函数,它可以根据一列或多列对数据进行分组,并且可以使用指定的表达式为汇总后的表添加新列,形成一张新表。 一:基础语法 SUMMARIZE函数的语法是:SUMMARIZE (表, 分组列1 [, 分组列2]… [, 名称, 表达式]…