一、对I/O的理解
I/O(Input/Output)是计算机系统中与外部设备进行数据交换的过程。它涉及从外部设备(如硬盘、键盘、鼠标、网络等)读取数据到计算机系统,以及将数据从计算机系统写入外部设备的操作。
在计算机系统中,I/O 是非常重要的,因为它使得计算机能够与用户交互、处理文件、进行网络通信等。下面是对 I/O 的一些基本概念和理解:
-
输入(Input):从外部设备读取数据到计算机系统的过程。例如,从键盘读取用户输入、从文件读取数据等。
-
输出(Output):将计算机系统的数据发送到外部设备的过程。例如,将数据写入文件、将数据显示在屏幕上等。
-
流(Stream):在 I/O 操作中,数据是通过流的方式进行传输的。流是一个抽象的概念,表示数据的连续序列。流可以是字节流(Byte Stream)或字符流(Character Stream)。
-
字节流(Byte Stream):以字节为单位进行传输的流。字节流通常用于处理二进制数据,例如读取或写入图像、音频等文件。
-
字符流(Character Stream):以字符为单位进行传输的流。字符流通常用于处理文本数据,提供了更高层次的字符操作,例如读取或写入文本文件。
-
输入流(Input Stream):用于从外部设备读取数据的流。输入流提供了不同的方法用于读取数据,例如
read()
方法用于逐个字节读取数据。 -
输出流(Output Stream):用于将数据写入外部设备的流。输出流提供了不同的方法用于写入数据,例如
write()
方法用于逐个字节写入数据。 -
缓冲(Buffering):为了提高 I/O 性能,系统通常会引入缓冲区(Buffer)来减少实际的物理读写次数。缓冲区可以暂存一定量的数据,当达到一定条件时进行一次实际的 I/O 操作。
-
阻塞式 I/O(Blocking I/O):在进行 I/O 操作时,程序会阻塞等待操作完成。阻塞式 I/O 是一种同步的方式,即程序在进行 I/O 操作时会被阻塞,直到操作完成后才继续执行。
-
非阻塞式 I/O(Non-blocking I/O):在进行 I/O 操作时,程序不会阻塞等待操作完成,而是立即返回并继续执行其他任务。程序可以通过轮询或回调等方式来获取操作的完成状态。
-
同步 I/O(Synchronous I/O):在进行 I/O 操作时,程序需要等待操作完成并返回结果后才能继续执行。同步 I/O 是一种阻塞式的方式,程序会阻塞等待 I/O 操作的完成。
-
异步 I/O(Asynchronous I/O):在进行 I/O 操作时,程序可以继续执行其他任务,而不需要等待操作完成。程序可以通过回调或事件通知等方式来处理操作的结果。
二、BIO
同步并阻塞(传统阻塞型),服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销
三、NIO
同步非阻塞,服务器实现模式为一个线程处理多个请求(连接),即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求就进行处理
四、AIO
异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由操作系统先完成了再通知服务器应用去启动线程进行处理,一般适用于连接数较多且连接时间较长的应用
五、三种I/O的区别
BIO (Blocking I/O):同步阻塞 I/O 模式。
NIO (New I/O):同步非阻塞模式。
AIO (Asynchronous I/O):异步非阻塞 I/O 模型。
同步阻塞模式:这种模式下,我们的工作模式是先来到厨房,开始烧水,并坐在水壶面前一直等着水烧开。
同步非阻塞模式:这种模式下,我们的工作模式是先来到厨房,开始烧水,但是我们不一直坐在水壶前面等,而是回到客厅看电视,然后每隔几分钟到厨房看一下水有没有烧开。
异步非阻塞 I/O 模型:这种模式下,我们的工作模式是先来到厨房,开始烧水,我们不一直坐在水壶前面等,也不隔一段时间去看一下,而是在客厅看电视,水壶上面有个开关,水烧开之后他会通知我。
阻塞 VS 非阻塞:人是否坐在水壶前面一直等。
同步 VS 异步:水壶是不是在水烧开之后主动通知人。
六、三种使用场景
BIO 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4 以前的唯一选择,但程序直观简单易理解。采用阻塞式 I/O 模型,线程在执行 I/O 操作时被阻塞,无法处理其他任务,适用于连接数较少且稳定的场景。
NIO 方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4 开始支持。使用非阻塞 I/O 模型,线程在等待 I/O 时可执行其他任务,通过 Selector 监控多个 Channel 上的事件,提高性能和可伸缩性,适用于高并发场景。
AIO 方式适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用 OS 参与并发操作,编程比较复杂,JDK7 开始支持。采用异步 I/O 模型,线程发起 I/O 请求后立即返回,当 I/O 操作完成时通过回调函数通知线程,进一步提高了并发处理能力,适用于高吞吐量场景。