BIO、NIO、AIO

BIO:(同步 阻塞)jdk1.4以前

java.io包 NIO:(同步 非阻塞)jdk1.4

java.nio包 AIO:(异步 非阻塞)jdk1.7 java.nio包

如何如何理解

当我们去吃饭可以有以下几种模式:

饭店 -> 服务器

饭菜-> 数据

饭菜好了-> 数据就绪

端菜 /送菜 -> 数据读取

BIO:食堂排队打饭模式:排队在窗口,打好才走;

NIO:点单、等待被叫模式:等待被叫,好了自己去端;

AIO:包厢模式:点单后菜直接被端上桌。

阻塞与非阻塞

菜没好,要不要死等 -> 数据就绪前要不要等待?
阻塞: 没有数据传过来时,读会阻塞直到有数据;缓冲区满时,写操作也会阻塞。
非阻塞: 遇到这些情况,都是直接返回

同步与异步

菜好了,谁端 -> 数据就绪后,数据操作谁完成?
同步: 数据就绪后需要自己去读是同步
异步: 数据就绪直接读好再回调给程序是异步

一般是不建议使用BIO的,原因如下: 连接数高的情况下:阻塞 -> 耗资源、效率低
Linux系统也是不推荐使用AIO的,原因如下:

Windows 实现成熟,但是很少用来做服务器

Linux 常用来做服务器,但是 AIO 实现不够成熟

Linux 下 AIO 相比较 NIO 的性能提升不明显

JDK中的NIO

NIO 库是在 JDK 1.4 中引入的。NIO 弥补了原来的 I/O 的不足,它在标准 Java 代码中提供了高速的、面向块的 I/O。NIO翻译成 no-blocking io 或者 new io都说得通。

NIO和BIO的主要区别

面向流与面向缓冲

Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。

Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。

阻塞与非阻塞IO

Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。

Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。

NIO三大核心组件

NIO有三大核心组件:Selector选择器、Channel管道、buffer缓冲区。

buffer缓冲区

网络通讯中负责数据读写的区域

Channel

通道,被建立的一个应用程序和操作系统交互事件、传递内容的渠道(注意是连接到操作系统)。那么既然是和操作系统进行内容的传递,那么说明应用程序可以通过通道读取数据,也可以通过通道向操作系统写数据,而且可以同时进行读写。

  • 所有被Selector(选择器)注册的通道,只能是继承了SelectableChannel类的子类。
  • ServerSocketChannel:应用服务器程序的监听通道。只有通过这个通道,应用程序才能向操作
    系统注册支持"多路复用IO"的端口监听。同时支持UDP协议和TCP协议。
  • ScoketChannel:TCP Socket套接字的监听通道,一个Socket套接字对应了一个客户端IP:端口到服务器IP:端口的通信连接。
  • SocketChannel 客户端主动连接服务器(connect()),或服务端通过 accept() 获取
  • ServerSocketChannel 服务端绑定端口并注册到 Selector,监听 OP_ACCEPT 事件

通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。

Selector

Selector的英文含义是"选择器",也可以称为为"轮询代理器"、"事件订阅器"、"channel容器管理机"都行。

Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器(Selectors),然后使用一个单独的线程来操作这个选择器,进而"选择"通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

应用程序将向Selector对象注册需要它关注的Channel,以及具体的某一个Channel会对哪些IO事件感兴趣。Selector中也会维护一个"已经注册的Channel"的容器。

相关推荐
灯澜忆梦14 小时前
GO_并发编程---定时器
开发语言·后端·golang
阳光是sunny14 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
皮皮林55114 小时前
开源实力派,给本地 AI 装上深度调研能力,一张 3090 跑到 95.7 分!
后端
努力的小雨15 小时前
把 Windows 桌面图标做成一个会自己运转的小世界
后端
武子康15 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端
腾渊信息科技公司16 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
IT_陈寒17 小时前
Vue这个特性差点让我加班到凌晨,谁懂啊
前端·人工智能·后端
段一凡-华北理工大学17 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
码事漫谈18 小时前
1999年的电商前夜和2026年的AI前夜 历史押韵但从不重复
后端
Conan在掘金18 小时前
鸿蒙报错速查:arkts-strict-typing Property does not exist on type 'object',object 装函数就炸,根因 + 真解法
后端