JVM中通过NIO的Pipe管道实现同一JVM内两个独立线程极速数据单向传输的原理

秋磊小哥_6728

秋磊小哥_6728

2026-06-07

325人浏览

原创

java nio pipe通过内核级环形缓冲区实现线程间零拷贝单向传输,非阻塞模式下延迟极低,但缓冲区固定约8 kib、无背压机制且不支持selector注册。

jvm中通过nio的pipe管道实现同一jvm内两个独立线程极速数据单向传输的原理

Java NIO 的 Pipe 在同一 JVM 内实现两个线程间极速单向数据传输,核心在于它复用了操作系统内核级的管道机制(如 Unix domain pipe),全程不经过堆外拷贝、不依赖锁、不触发 GC 频繁分配,数据从写线程的 ByteBuffer 直达读线程可读位置,延迟极低。

底层是内核环形缓冲区,零用户态拷贝

Pipe.open() 实际在内核中创建了一个固定大小(OpenJDK 默认约 8 KiB)的匿名管道,SinkChannel 和 SourceChannel 共享同一段内核内存。写入时,JVM 将 ByteBuffer 中的数据通过系统调用(如 write())送入该缓冲区;读取时,再通过 read() 直接从该缓冲区拉取——整个过程不经过 JVM 堆内存中转,也无需序列化或对象封装。

  • 数据流路径:写线程 ByteBuffer → 内核管道缓冲区 → 读线程 ByteBuffer(无中间复制)
  • 没有 Socket 的协议解析开销,也没有文件 I/O 的磁盘寻址延迟
  • 相比 BlockingQueue<bytebuffer></bytebuffer>,省去了队列加锁、节点对象创建、GC 压力等环节

非阻塞 + 显式状态管理,避免线程挂起

默认阻塞模式下,Pipe 会因缓冲区满/空导致线程卡死,完全丧失“极速”特性。真正发挥性能的前提是两端均设为非阻塞:

悟空
悟空

一款AI办公效率工具,主要用于阿里巴巴旗下钉钉推出的AI原生智能体工作台,适合需要提升相关任务效率的用户。

下载
  • sink.configureBlocking(false):write() 立即返回,返回值即实际写入字节数;为 0 表示缓冲区满,需稍后重试,而非等待
  • source.configureBlocking(false):read() 同样立即返回,-1 表示管道已关闭,0 表示暂无数据,不阻塞
  • 配合 buffer.flip() / buffer.clear() 精确控制读写边界,避免因 buffer 状态错乱导致读不到数据

线程安全且无锁,天然适配生产者-消费者模型

Pipe 的 SinkChannel 和 SourceChannel 是 JDK 内部保证线程安全的通道,其 write/read 操作由内核原子保障,应用层无需额外同步:

  • 多个写线程可并发调用同一 SinkChannel.write(),数据按写入顺序串行进入管道
  • 单一读线程从 SourceChannel 读取,天然形成“多对一”的生产者-消费者结构
  • 无 synchronized、无 CAS 自旋、无 AQS 队列,规避了锁竞争和上下文切换开销

限制与适用边界:快,但不是万能高速路

Pipe 的“极速”体现在低延迟、小数据、短链路场景,但它有明确瓶颈:

  • 缓冲区大小不可配置(固定 ~8 KiB),大消息需分片,频繁小包易引发过多系统调用
  • 无背压反馈机制,写入过快会导致 write() 持续返回 0,需应用层主动退让(如 Thread.yield() 或交由 Selector 调度)
  • SourceChannel 和 SinkChannel 不支持注册到 Selector(会抛 UnsupportedOperationException),所谓“用 Selector 管理 Pipe”是常见误用
  • 不适合高吞吐、长连接、需动态路由或多消费者广播的场景——此时 TransferQueue 或自定义 ring buffer 更稳

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
pip安装使用方法
pip安装使用方法

安装步骤:1、确保Python已经正确安装在您的计算机上;2、下载“get-pip.py”脚本;3、按下Win + R键,然后输入cmd并按下Enter键来打开命令行窗口;4、在命令行窗口中,使用cd命令切换到“get-pip.py”所在的目录;5、执行安装命令;6、验证安装结果即可。大家可以访问本专题下的文章,了解pip安装使用方法的更多内容。

2023.10.09

2730

5

更新pip版本
更新pip版本

更新pip版本方法有使用pip自身更新、使用操作系统自带的包管理工具、使用python包管理工具、手动安装最新版本。想了解更多相关的内容,请阅读专题下面的文章。

2024.12.20

6283

6

pip设置清华源
pip设置清华源

设置方法:1、打开终端或命令提示符窗口;2、运行“touch ~/.pip/pip.conf”命令创建一个名为pip的配置文件;3、打开pip.conf文件,然后添加“[global];index-url = https://pypi.tuna.tsinghua.edu.cn/simple”内容,这将把pip的镜像源设置为清华大学的镜像源;4、保存并关闭文件即可。

2024.12.23

7862

11

python升级pip
python升级pip

本专题整合了python升级pip相关教程,阅读下面的文章了解更多详细内容。

2025.07.23

3887

16

Java I/O 与 NIO 编程体系合集
Java I/O 与 NIO 编程体系合集

全面讲解 Java I/O 编程的演进与核心 API,涵盖传统 I/O 的字节流(InputStream/OutputStream)与字符流(Reader/Writer)体系、装饰器模式在 I/O 中的应用(BufferedReader/InputStreamReader)、文件读写与目录操作、NIO 核心三要素(Buffer 缓冲区/Channel 通道/Selector 选择器)、ByteBuffer 操作与内存映射文件(Mappe

2026.04.29

352

28

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

3858

6

FrankenPHP集成Laravel详细教程
FrankenPHP集成Laravel详细教程

本专题提供FrankenPHP集成Laravel的详细配置指南,全面解析运行原理、开发环境搭建、Caddyfile配置、Octane工作模式、数据库连接、队列任务、定时任务和生产环境优化,解决部署过程中常见的报错与兼容性问题。

2026.10.08

0

20

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

2026.09.30

120

10

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

2026.09.30

100

14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习