news 2026/5/1 6:23:35

BIO/NIO/AIO/Netty 知识点

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
BIO/NIO/AIO/Netty 知识点

I/O 的概念

I/O(Input/Output)指输入输出操作,是程序与外部设备(如磁盘、网络、键盘等)交互的过程。核心目标是实现数据的高效读写,分为磁盘 I/O、网络 I/O 等类型。


同步 vs 异步、阻塞 vs 非阻塞

同步/异步:关注任务完成的通知机制。同步需等待任务完成,异步通过回调或事件通知。
阻塞/非阻塞:关注等待时的线程状态。阻塞会挂起线程,非阻塞立即返回状态。

示例:

  • 同步阻塞:读取文件时线程阻塞直到数据就绪。
  • 异步非阻塞:通过回调通知数据就绪,线程可处理其他任务。

BIO(Blocking I/O)

BIO 是同步阻塞模型,每个连接需独立线程处理。线程在读写时阻塞直到操作完成。
示例:

ServerSocketserverSocket=newServerSocket(8080);while(true){Socketsocket=serverSocket.accept();// 阻塞newThread(()->handleRequest(socket)).start();}

NIO(Non-blocking I/O)

NIO 是同步非阻塞模型,通过 Selector 监听多个 Channel 的事件(如读写就绪),避免线程阻塞。
核心组件:

  • Channel:双向数据传输通道。
  • Buffer:数据容器。
  • Selector:多路事件监听器。

示例:

Selectorselector=Selector.open();channel.configureBlocking(false);channel.register(selector,SelectionKey.OP_READ);while(true){selector.select();// 阻塞直到事件就绪Set<SelectionKey>keys=selector.selectedKeys();// 处理事件...}

AIO(Asynchronous I/O)

AIO 是异步非阻塞模型,操作系统完成 I/O 后主动回调,无需线程轮询。
核心类:

  • AsynchronousSocketChannel
  • CompletionHandler

示例:

AsynchronousServerSocketChannelserver=AsynchronousServerSocketChannel.open();server.bind(newInetSocketAddress(8080));server.accept(null,newCompletionHandler<AsynchronousSocketChannel,Void>(){@Overridepublicvoidcompleted(AsynchronousSocketChannelclient,Voidattachment){// 处理连接...}});

Netty 简介

Netty 是基于 NIO 的高性能网络框架,提供事件驱动、零拷贝等特性,简化 NIO 编程。
核心优势

  • 线程模型优化(如主从 Reactor)。
  • 解决粘包/半包问题(如 LengthFieldBasedFrameDecoder)。

BIO、NIO、AIO 的区别

特性BIONIOAIO
模型同步阻塞同步非阻塞异步非阻塞
线程开销高(1连接1线程)低(多路复用)极低(回调驱动)
适用场景低并发高并发短连接高并发长连接

Java IO 流分类

  1. 按方向
    • 输入流(InputStream/Reader)
    • 输出流(OutputStream/Writer)
  2. 按单位
    • 字节流(操作二进制数据)
    • 字符流(处理文本,如 FileReader)

内核空间

内核空间是操作系统核心代码的运行区域,用户程序需通过系统调用(如read())访问硬件资源。I/O 操作本质是数据在用户空间与内核空间之间的拷贝。


五种 I/O 模型

  1. 阻塞 I/O
  2. 非阻塞 I/O
  3. I/O 多路复用(如 select/poll/epoll)
  4. 信号驱动 I/O
  5. 异步 I/O(如 AIO)

Bit、Byte、Char 的区别

  • Bit:二进制最小单位(0/1)。
  • Byte:8 bits,存储基本数据类型(如byte)。
  • Char:16 bits(Java 中),表示 Unicode 字符。

对象序列化与反序列化

序列化:将对象转换为字节流(如网络传输或持久化)。
反序列化:将字节流恢复为对象。
示例:

ObjectOutputStreamoos=newObjectOutputStream(newFileOutputStream("data.obj"));oos.writeObject(myObject);// 序列化

serialVersionUID 的作用

用于版本控制,确保序列化与反序列化的类兼容。未显式定义时,JVM 自动生成,但类结构变化可能导致反序列化失败。

生成方式:

privatestaticfinallongserialVersionUID=1L;// 手动指定

BufferedReader

属于字符缓冲流,提升读取效率。
常用方法:

  • readLine():读取一行文本。
  • close():关闭流。

Java IO 流顶级超类

  • 字节流:InputStreamOutputStream
  • 字符流:ReaderWriter

图片/视频必须用字节流

媒体文件是二进制数据,字符流可能因编码转换损坏内容。字节流(如FileInputStream)直接操作原始字节。


BIO 服务端为何多线程

单线程处理连接时会阻塞,无法并发响应。多线程允许同时处理多个客户端请求,但线程开销大(C10K 问题)。


多线程 BIO 瓶颈

  • 线程创建/销毁成本高。
  • 线程数过多导致上下文切换频繁,CPU 利用率下降。

线程池能否彻底解决 BIO

不能。线程池仅缓解线程创建开销,但高并发时仍受限于线程数量(如池满后请求排队)。


NIO 核心组件

  1. Channel:数据传输管道(如SocketChannel)。
  2. Buffer:数据容器(如ByteBuffer)。
  3. Selector:监听多个 Channel 的事件。

Buffer 重要属性

  • capacity:缓冲区容量。
  • position:当前读写位置。
  • limit:可操作数据边界。
  • flip():切换读写模式。

Selector 工作原理

通过系统调用(如epoll)监听注册的 Channel,当 I/O 事件(如读就绪)发生时,返回可处理的 SelectionKey 集合。


NIO 编程难点

  • 事件处理逻辑复杂(需管理 Buffer、Channel 状态)。
  • 需处理半包/粘包问题(如自定义编解码器)。

AIO 核心类

  • AsynchronousFileChannel:异步文件操作。
  • AsynchronousSocketChannel:异步网络通信。

Netty 线程模型

主从 Reactor 模式:

  • BossGroup:处理连接请求。
  • WorkerGroup:处理 I/O 事件。
  • 每个 Channel 绑定到固定 EventLoop 避免竞争。

Netty 解决粘包/半包

  • 固定长度解码器FixedLengthFrameDecoder)。
  • 分隔符解码器DelimiterBasedFrameDecoder)。
  • 长度字段解码器LengthFieldBasedFrameDecoder)。

Netty 零拷贝

  • Direct Buffer:避免 JVM 堆与 Native 内存拷贝。
  • CompositeByteBuf:合并多个 Buffer 减少拷贝次数。
  • 文件传输:通过FileRegion直接发送文件。

Netty 心跳机制

使用IdleStateHandler检测空闲连接:

pipeline.addLast(newIdleStateHandler(30,0,0,TimeUnit.SECONDS));pipeline.addLast(newHeartbeatHandler());

ChannelPipeline

责任链模式,包含一系列 ChannelHandler,按顺序处理入站/出站事件。示例:

pipeline.addLast(newDecoderHandler());pipeline.addLast(newBusinessLogicHandler());

Linux 底层支持

  • BIO:基于系统调用read()/write()
  • NIO:基于epoll(高效多路复用)。
  • AIO:依赖 Linux 的io_uring或 glibc 的线程池模拟。

Netty 不直接用 AIO

  • Linux AIO 对非文件 I/O 支持不完善。
  • NIO(epoll)已满足高性能需求,且更稳定。

优化 Netty 性能

  • 调整 EventLoopGroup 线程数(通常为 CPU 核数 * 2)。
  • 使用对象池(如Recycler)减少 GC 压力。
  • 开启 Native EPoll(EpollEventLoopGroup)。

Netty 内存泄漏排查

  • 启用ResourceLeakDetector
    System.setProperty("io.netty.leakDetection.level","PARANOID");
  • 检查未释放的 ByteBuf 或 Channel。

Netty 应用案例

  • Dubbo:RPC 框架。
  • RocketMQ:消息队列。
  • Elasticsearch:分布式搜索。
  • Spring WebFlux:响应式 Web 框架。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 3:50:43

621-3580RC输入模块

621-3580RC 输入模块621-3580RC 是工业自动化控制系统中的 数字/离散输入模块&#xff0c;用于接收现场开关、传感器或其他数字设备的信号&#xff0c;并将其传递给控制系统进行处理。核心作用信号采集&#xff1a;将现场数字量&#xff08;开关状态、继电器信号等&#xff09;…

作者头像 李华
网站建设 2026/5/1 3:49:21

工厂查询工具这么用,才能避开“空壳工厂”和“无效联系方式”

在制造业的B2B合作过程里&#xff0c;要寻找到一家所谓的“工厂”好像是一件十分容易的事情&#xff0c;你只要打开任意一个企业查询平台&#xff0c;然后在搜索栏中输入相关的关键词&#xff0c;这时候成百上千条查询结果就会在瞬间展示出来&#xff0c;其实事实上&#xff0c…

作者头像 李华
网站建设 2026/5/1 3:44:51

宏智树AI开题报告攻略:从格式到逻辑,新手也能一次过

作为深耕论文写作科普的博主&#xff0c;后台最常收到的求助就是&#xff1a;“开题报告怎么写才不被导师打回&#xff1f;”“12大核心模块&#xff0c;越写越混乱怎么办&#xff1f;” 开题报告作为论文的“蓝图”&#xff0c;涵盖研究背景、文献综述、研究方法等12个核心部分…

作者头像 李华
网站建设 2026/5/1 4:44:03

java_ssm16养老院床位安排老年健康登记服务平台设计与实现85kwy

目录 具体实现截图摘要关键词 系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 具体实现截图 摘要 该系统基于Java SSM框架&#xff08;Spring、Spring MVC、MyBatis&#xff09;开发&#xff0c;旨在为养老院…

作者头像 李华
网站建设 2026/5/1 4:44:06

【Jmeter】深度解剖Jmeter的二次开发

JMeter 是一个功能强大的性能测试工具&#xff0c;但它可能无法满足特定项目或组织的特定需求。通过进行二次开发&#xff0c;可以定制 JMeter&#xff0c;使其适应具体项目的需求。例如&#xff0c;可能需要添加自定义的测试元件、报告生成器或结果分析器等。二次开发三种方式…

作者头像 李华
网站建设 2026/5/1 4:44:05

AI的诗歌:叶子从树上落下不是告别

480、叶——灵遁者叶子从树上落下不是告别是把阳光重新藏进泥土等明年再开花481、风——灵遁者风在巷子里跑撞翻了蒲公英的伞吹乱了云朵的稿最后停在我的耳边说&#xff1a;世界是块没拼好的拼图482、时钟的褶皱——灵遁者秒针在玻璃罩里折纸把清晨叠成邮戳大小的黄昏我数着它反…

作者头像 李华