还不懂BIO,NIO,AIO吗

2024-09-08 11:28
文章标签 nio aio bio

本文主要是介绍还不懂BIO,NIO,AIO吗,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

BIO(Blocking I/O)、NIO(Non-blocking I/O)和 AIO(Asynchronous I/O)是 Java 中三种不同的 I/O 模型,主要用于处理输入 / 输出操作。

一、BIO(Blocking I/O)

  1. 定义与工作原理:

    • BIO 即阻塞式 I/O(同步阻塞,传统IO)。在这种模型下,当一个线程发起一个 I/O 操作(如读取文件或网络数据)时,此线程会被阻塞,直到操作完成才返回。

    • 例如,当一个程序使用 BIO 从网络读取数据时,发起读取操作的线程会一直等待数据到来,在此期间不能进行其他操作。

  2. 缺点:

    • 代码中的read,accept操作时阻塞操作,如果客户端连接服务器后,服务器不发送数据,将会一直阻塞当前线程,浪费资源

    • 若连接数很多,创建的线程数量也多,服务器压力很大,后续优化成线程池处理方式,勉强解决了此问题。

  3. 适用场景:

    • 适用于连接数目比较小且固定的架构,这种模式对服务器资源要求较高,但程序复杂度比较低。

    • 例如,一些简单的文件传输程序或者小型的服务器应用,连接数量有限且对性能要求不高。

    • Socket通信

二、NIO(Non-blocking I/O)

NIO在BIO的基础上进行了升级,将阻塞换成非阻塞,虽然只是模式变了下,但是代码复杂量却增加了不少。在NIO模型中,服务端可以开启一个线程处理多个连接,它是非阻塞的,客户端发送的数据都会注册到多路复用器selector上面,当selector (selector的select方法是阻塞的)轮询到有读、写或者连接请求时,才会转发到后端程序进行处理,没有数据的时候,业务程序并不需要阻塞等待。

数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。

  1. 定义与工作原理:

    • NIO 即非阻塞式 I/O(同步非阻塞)。在这种模型下,当线程发起一个 I/O 操作时,它不会被阻塞,而是立即返回。线程可以通过轮询的方式不断检查 I/O 操作是否完成。

    • 例如,使用 NIO 从网络读取数据时,线程发起读取操作后会立即返回,然后可以继续执行其他任务。过一段时间后,线程再回来检查读取操作是否完成。

  2. 适用场景:

    • 适用于连接数目多且连接时间短的架构,比如聊天服务器等。

    • 例如,在一个高并发的即时通讯服务器中,可能同时有大量的客户端连接和断开。使用 NIO 可以在一个线程中处理多个连接的 I/O 操作,提高服务器的性能和可扩展性。

NIO有三大组件:

Channel(通道)、Buffer (缓存区)、Selector(选择器) Channel 类似于流,但是它是一个双向的流,他是连接服务端和客户端的通道,不管是客户端还是服务端,都可以使用通道进行读写数据。 Buffer 它就是一个缓冲区,用来存放数据的载体,它借助通道,在客户端和服务端之间传递数据 Selector 它对应一个或多个channel,客户端的连接都会注册到selector上面,然后由selector去调用后端处理程序

备注:

 Channel

首先说一下 Channel,国内大多翻译成“通道”。Channel 和 IO 中的 Stream(流)是差不多一个

等级的。只不过 Stream 是单向的,譬如:InputStream, OutputStream,而 Channel 是双向

的,既可以用来进行读操作,又可以用来进行写操作。

NIO 中的 Channel 的主要实现有:

\1. FileChannel

\2. DatagramChannel

\3. SocketChannel

\4. ServerSocketChannel

这里看名字就可以猜出个所以然来:分别可以对应文件 IO、UDP 和 TCP(Server 和 Client)。

下面演示的案例基本上就是围绕这 4 个类型的 Channel 进行陈述的。

 Buffer

Buffer,故名思意,缓冲区,实际上是一个容器,是一个连续数组。Channel 提供从文件、

网络读取数据的渠道,但是读取或写入的数据都必须经由 Buffer。

上面的图描述了从一个客户端向服务端发送数据,然后服务端接收数据的过程。客户端发送

数据时,必须先将数据存入 Buffer 中,然后将 Buffer 中的内容写入通道。服务端这边接收数据必

须通过 Channel 将数据读入到 Buffer 中,然后再从 Buffer 中取出数据来处理。

在 NIO 中,Buffer 是一个顶层父类,它是一个抽象类,常用的 Buffer 的子类有:

ByteBuffer、IntBuffer、 CharBuffer、 LongBuffer、 DoubleBuffer、FloatBuffer、

ShortBuffer

 Selector

Selector 类是 NIO 的核心类,Selector 能够检测多个注册的通道上是否有事件发生,如果有事

件发生,便获取事件然后针对每个事件进行相应的响应处理。这样一来,只是用一个单线程就可

以管理多个通道,也就是管理多个连接。这样使得只有在连接真正有读写事件发生时,才会调用

函数来进行读写,就大大地减少了系统开销,并且不必为每个连接都创建一个线程,不用去维护

多个线程,并且避免了多线程之间的上下文切换导致的开销

三、AIO(Asynchronous I/O)

  1. 定义与工作原理:

    • AIO 即异步 I/O。在这种模型下,当线程发起一个 I/O 操作后,它不需要等待操作完成,而是注册一个回调函数。当 I/O 操作完成时,系统会自动调用回调函数通知线程。

    • 例如,使用 AIO 从网络读取数据时,线程发起读取操作并注册一个回调函数,然后可以继续执行其他任务。当数据读取完成后,系统会自动调用回调函数,将数据传递给线程进行处理。

  2. 适用场景:

    • 适用于连接数目多且连接时间长的架构,对性能要求较高的场景。

    • 例如,大规模数据传输、高性能的文件服务器等。在这些场景下,AIO 可以充分发挥异步操作的优势,提高系统的吞吐量和响应速度。

四、区别总结

其实NIO基于BIO,AIO基于NIO,后面技术大多都基于NIO实现,如Netty

  1. 阻塞方式:

    • BIO 是完全阻塞的,线程在 I/O 操作期间一直等待。

    • NIO 是非阻塞的,线程可以在 I/O 操作期间执行其他任务,但需要不断轮询检查操作是否完成。

    • AIO 是异步的,线程在发起 I/O 操作后无需等待,而是通过回调函数获取结果。

  2. 线程使用:

    • BIO 通常为每个连接创建一个线程,资源消耗较大。

    • NIO 可以使用一个或几个线程处理多个连接,通过轮询的方式管理 I/O 操作。

    • AIO 通常由系统内核管理异步操作,减少了线程的开销。

  3. 适用场景:

    • BIO 适用于连接数量少、对性能要求不高的场景。

    • NIO 适用于连接数量较多、连接时间短的场景。

    • AIO 适用于连接数量多、连接时间长、对性能要求高的场景。

这篇关于还不懂BIO,NIO,AIO吗的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147977

相关文章

springboot体会BIO(阻塞式IO)

使用springboot体会阻塞式IO 大致的思路为: 创建一个socket服务端,监听socket通道,并打印出socket通道中的内容。 创建两个socket客户端,向socket服务端写入消息。 1.创建服务端 public class RedisServer {public static void main(String[] args) throws IOException {

【虚拟化】AIO主机安装PVE8,配置网络,安装win11(virtio,qcow2,scsi,oobe,adk)

【虚拟化】AIO主机安装PVE8,配置网络,安装win11(virtio,qcow2,scsi,oobe,adk) 文章目录 1、ESXI vs PVE,AIO主机系统二选一2、PVE网络配置(DNS,换源,网卡,https,概览)3、win11虚拟化配置(virtio,raw,qcow2)附,域名解析,rocky9.4,黑群晖 1、ESXI vs PVE,AIO主机系统二选

JAVA NIO的笔记

Java中的NIO IO-文件的读写 NIO是Java4开始提供的用来解决IO问题的API。 Channel(通道)  Buffer(缓存区)  Selector(选择器) inputStream outPutStream 都是以Stream为观点看的 所以input为读 output为写 两个对象文件盒stream Channel读写操作都能做 Channel是执行读写操作这个工作的东西 而读写

Java高级特性增强-NIO

GitHub:https://github.com/wangzhiwubigdata/God-Of-BigData 关注公众号,内推,面试,资源下载,关注更多大数据技术~大数据成神之路~预计更新500+篇文章,已经更新50+篇~ **Java高级特性增强-NIO 本部分网络上有大量的资源可以参考,在这里做了部分整理并做了部分勘误,感谢前辈的付出,每

Java - NIO之Channel(FileChannel)

一、关于Channel     Java NIO的通道(Channel)类似流,但又有些不同:         既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。         通道可以异步地读写。         通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。       Java NIO中最重要的通道的实现:

Error:Artifact com.*******:war exploded: java.nio.file.InvalidPathException: Illeg

由于一次电脑蓝屏,Idea启动tomcat报错: Error:Artifact ':war exploded’: java.nio.file.InvalidPathException: Illegal char < > at index 71: K:\COMPANY_CODE_IDEA\FLOW_CODE*\target\activ : Illegal char < > at index 71:

Java 输入与输出之 NIO.2【AIO】【Path、Paths、Files】【walkFileTree接口】探索之【三】

在JDK 1.7 版本中对NIO进行了完善,推出了NIO.2,也称为AIO(异步IO),在处理大量并发请求时具有优势,特别是在网络编程和高并发场景下,表现得更为出色。 对于输出流和输入流而言,操作的对象可以是文件,大多数情况下是文件,也可以是网络连接,当然也可以是内存数据。我们今天主要讨论的是文件和目录处理。 本博客我们将探讨NIO.2中最基础的Path、Paths和Files的用法。 Path

Java NIO 核心知识总结

Java NIO 核心知识总结 NIO简介 在传统的I/O模型中,是以阻塞的方式进行的也就是当一个线程执行的时候线程会一直阻塞到完成工作为止。这种模型的缺点就是在并发比较大的时候性能就会比较低,并且在每次都要给一个新的任务(连接)创建一个新的线程,这个新的线程的创建和从上一个切换到这一个线程都会都性能有影响。 为了优化这个传统的io模型,在jdk1.4新引入了一个全新的new io包,在原有

Linux实现异步IO的方法:epoll,posix aio,libaio,io_uring

Linux中异步IO的实现方式大概有以下几种: 1. epoll 熟悉网络编程的人可能会想到select,poll,epoll这些异步IO的方式,但实际上这些方式叫做非阻塞IO,用于把网络读写的阻塞变成非阻塞,并不是实际意义上的异步IO。因此Epoll这些只能用于实现非阻塞的Socket IO,无法用于异步的Storage IO。 因为只有网络IO才存在阻塞的情况(也即,这个网络文件描述符是否

Java程序员从笨鸟到菜鸟(四十三)NIO 非阻塞实现高并发

一、阻塞和非阻塞 阻塞:应用程序在获取网络数据的时候,如果网络传输很慢,就会一直等待直到传输完毕为止 非阻塞:应用程序可以直接获取已经准备就序好的数据,无需等待 二、BIO、NIO、AIO BIO(同步阻塞式 IO):服务器实现模式为一个请求一个线程,客户端有连接请求是服务器就需要启动一个线程进行处理,如果这个连接不做任何事情就造成不必要的开销 NIO(同步非阻塞式IO):服务器实现模式