Java 中 IO 之 BIO、NIO 和 AIO

简介: IO 是 Input 和 Output 二词的缩写,意为输入和输出,直接来说,实现一般的 I/O 是没有什么难度的,但涉及到多线程时,要解决 I/O 的问题就不是一个简单的事情了,会涉及到同步和异步的问题,阻塞和非阻塞的问题。了解了(非)同步和(非)阻塞之后,我们再来看 I/O,根据是否同步和是否阻塞以及按它们出现的时间顺序,主要划分为 3 种 I/O 技术,分别是 BIO、NIO 和 AIO。当然,并不是只有这几种,还有其他的 I/O 类型。

一、IO

IO 是 Input 和 Output 二词的缩写,意为输入和输出,直接来说,实现一般的 I/O 是没有什么难度的,但涉及到多线程时,要解决 I/O 的问题就不是一个简单的事情了,会涉及到同步和异步的问题,阻塞和非阻塞的问题。

1.1 同步和异步

同步可以借用多线程来方便理解,多条线程,从字面意思上来看,当他们在同一直线上时,就是同步,反之则是异步。那什么是在同一直线上呢?简单说就是,它们都在处理同时事件,比如同时运行某个函数,调用或修改某个变量。

从这里我们不难看出,同步有时是会产生一些问题的,比如同时修改某个变量。从现实角度来看,这是不可能修改成功的,毕竟是完完全全同时嘛。但是,我们知道计算机的每个 CPU 执行多线程实际并非真的同时干两个事情,它只是将时间分片了,一会儿做这个线程的事情,一会做另外一个线程的事情,由于 CPU 切换任务和执行任务的速度非常非常快,因此从宏观时间尺度上来看,就好像多个线程在同时运行,但实际在微观时间尺度上,它们仍然是单线程的。

多线程

接上面的说,那么计算机的两个线程同时修改某个变量后,必然有一个线程先对这个变量进行修改,另外一个线程再对这个线程进行修改,由于分片数量和执行速度不能保证完完全全相同,所以我们无法预测到底是哪个线程先对这个变量进行的修改,那么这就会产生一系列无法预知的问题。为此,异步操作诞生了!

从程序优化的角度上看,异步操作优于同步操作,但相应地,实现难度会大一些。

1.2 阻塞和非阻塞

最典型的阻塞就是终端等待用户输入,Java 里面使用 Scanner 类时,在不做多线程等处理时,要一直等到用户在终端输入字符后,Scanner 类后面的代码才能运行。而非阻塞呢,在界面编程里面体现的非常明显,窗口的显示实际可以看作是一个大循环,它在每一次循环中都在刷新着窗口,但我们在窗口中的操作并运行一些计算的时候呢,界面也一直都在,它并不会因为我们操作了什么而产生了阻塞,导致窗口没有变化(不刷新)了。

从阻塞和非阻塞的含义上来看,大部分时间我们都希望程序是非阻塞的,因为阻塞的情况下,阻塞处后面的程序无法运行,这就浪费计算机的性能了,等阻塞完之后再执行后面的程序,会产生时间上的消耗,使用户产生延迟感,这是不好的,为了解决这个问题,非阻塞操作产生了!

从程序优化的角度上看,非阻塞操作优于阻塞操作,但相应地,非阻塞的实现难度大一些。

了解了(非)同步和(非)阻塞之后,我们再来看 I/O,根据是否同步和是否阻塞以及按它们出现的时间顺序,主要划分为 3 种 I/O 技术,分别是 BIO、NIO 和 AIO。当然,并不是只有这几种,还有其他的 I/O 类型。

二、BIO

BIO 是 Blocking I/O 的缩写,意为同步阻塞式 I/O,Blocking 是阻塞的意思。

BIO 是最基本的 I/O 处理模式。在这种模式下,当一个 I/O 操作正在进行时,会阻塞其他所有操作,直到这个 I/O 操作完成。这种模式的优点是编程模型简单,适合请求不高并发、任务简单的场景。但是,对于高并发的场景,BIO 可能会导致大量的线程阻塞,消耗大量的系统资源,性能较低。

三、NIO

NIO 是 Non-blocking I/O 的缩写,代表同步非阻塞式 I/O,Non-blocking 是非阻塞意思。

NIO 是对 BIO 的一种改进。在这种模式下,当一个 I/O 操作正在进行时,不会阻塞其他操作。NIO 通过使用 Buffer(缓冲区)和 Channel(通道)进行数据的传输,以及使用 Selector(选择器)进行多路复用,可以同时处理多个客户端的连接和请求。这种模式的优点是可以处理高并发的场景,但是编程模型相对复杂。

下面是 NIO 的主要组件:

Channel(通道):Channel 是一个可以进行 I/O 操作的连接点。所有的数据都必须通过 Channel 读取或者写入。Channel 的主要实现包括 FileChannel(用于文件 I/O)、DatagramChannel(用于 UDP I/O)和 SocketChannel(用于 TCP I/O)。

Buffer(缓冲区):Buffer 是一个容器,用于在 Channel 和程序之间传输数据。当我们从 Channel 读取数据时,数据会被读入 Buffer;当我们向 Channel 写入数据时,数据会从 Buffer 写入。

Selector(选择器):Selector 是一个可以监控多个 Channel 的 I/O 状态(如:连接、读取、写入)的组件。通过 Selector,我们可以使用一个线程来处理多个 Channel 的 I/O 操作。

虽然 NIO 可以处理高并发场景,但当并发数量过大时,由于 NIO 的原理,它仍然会出现类似 BIO 阻塞的情况。

四、AIO

AIO 是 Asynchronous I/O 的缩写,意为异步非阻塞式 I/O,Asynchronous 是异步的意思。按照我们之前说的,这已经属于是效果最好,实现最难的 I/O 了。

AIO 是一种更高级的 I/O 处理模式。在这种模式下,一个 I/O 操作可以在后台异步地进行,当操作完成时,会通知相应的线程进行处理。这种模式的优点是可以处理高并发的场景,并且编程模型相对简单。但是,由于 AIO 是在操作系统级别进行异步操作,所以对操作系统的要求较高。

五、总结

按照时间出现的顺序,分别是 BIO、NIO 和 AIO,按照技术实现难度,分别是 BIO、NIO 和 AIO。总结为下表:

I/O BIO(同步阻塞式) NIO(同步非阻塞式) AIO(异步非阻塞式)
是否同步
是否非阻塞
出现时间 最早 中等 最迟
实现难度 简单 中等 困难
实现效果 中等
代码维护难度 中等

这三者的应用场景如下:

  • BIO 适用于单线程或少量并发的场景,每个 I/O 操作都会阻塞当前线程;
  • NIO 适用于需要处理大量并发连接的场景,一个线程可以同时处理多个 I/O 操作;
  • AIO 适用于需要处理大量并发操作且不希望线程阻塞的场景,通过回调函数处理 I/O 操作的完成;

有人就要问了,怎么没有 异步阻塞式 I/O 呢?这是个好问题。

异步阻塞式 I/O 也不是没有,只不过它的叫法与其他的不太一样,它叫做 I/O 多路复用(I/O Multiplexing)。这里不详细展开讲述了,后面会单独出一片文章进行讲解。

目录
相关文章
|
12月前
|
监控 Java API
现代 Java IO 高性能实践从原理到落地的高效实现路径与实战指南
本文深入解析现代Java高性能IO实践,涵盖异步非阻塞IO、操作系统优化、大文件处理、响应式网络编程与数据库访问,结合Netty、Reactor等技术落地高并发应用,助力构建高效可扩展的IO系统。
350 0
|
9月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
343 1
|
11月前
|
Java 测试技术 API
Java IO流(二):文件操作与NIO入门
本文详解Java NIO与传统IO的区别与优势,涵盖Path、Files类、Channel、Buffer、Selector等核心概念,深入讲解文件操作、目录遍历、NIO实战及性能优化技巧,适合处理大文件与高并发场景,助力高效IO编程与面试准备。
|
12月前
|
存储 Java Linux
操作系统层面视角下 Java IO 的演进路径及核心技术变革解析
本文从操作系统层面深入解析Java IO的演进历程,涵盖BIO、NIO、多路复用器及Netty等核心技术。分析各阶段IO模型的原理、优缺点及系统调用机制,探讨Java如何通过底层优化提升并发性能与数据处理效率,全面呈现IO技术的变革路径与发展趋势。
251 3
|
11月前
|
SQL Java 数据库连接
Java IO流(一):字节流与字符流基础
本文全面解析Java IO流,涵盖字节流、字符流及其使用场景,帮助开发者理解IO流分类与用途,掌握文件读写、编码转换、异常处理等核心技术,通过实战案例提升IO编程能力。
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
685 23
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
719 3
|
缓存 网络协议 Java
JAVA网络IO之NIO/BIO
本文介绍了Java网络编程的基础与历史演进,重点阐述了IO和Socket的概念。Java的IO分为设备和接口两部分,通过流、字节、字符等方式实现与外部的交互。
572 0
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
Java 大数据
如何在Java中进行网络编程:Socket与NIO
如何在Java中进行网络编程:Socket与NIO