恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Netty 源码剖析:MpscLinkedQueue 无锁多生产者单消费者队列的实现原理

  • 首页
  • 资讯中心
  • /
  • Netty 源码剖析:MpscLinkedQueue 无锁多生产者单消费者队列的实现原理

相关资讯

东华OJ第46-50题详解:数组、字符串、排序与算法基础入门 2026/9/13 2:41:03
Renovate Typst Manager:如何自动追踪并升级 .typ 文件中的 Typst 包版本 2026/9/13 2:41:03
Grafana+Polystat打造腾讯云监控大盘:50台主机一屏总览 2026/9/13 2:41:03

最新资讯

Roo Code 3.11.12:Grok3 流式输出支持与容错式 Diff 编辑深度解析
如何以最小修改把现有 PyTorch 自定义算子库迁移到 PaddlePaddle 上运行?
C++智能指针实战:unique_ptr、shared_ptr、weak_ptr用法与性能取舍
Windows下忘记PostgreSQL密码?修改pg_hba.conf快速重置
lo 库 Fill 函数深度解析:基于 Go 1.18+ 泛型的切片克隆填充
adk-python 代码单元设计文档模板:为 ADK 核心模块撰写“按实现如实记录“的架构设计文档

今日推荐

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

Netty 源码剖析:MpscLinkedQueue 无锁多生产者单消费者队列的实现原理

发布时间:2026/9/13 2:41:03
Netty 源码剖析:MpscLinkedQueue 无锁多生产者单消费者队列的实现原理 Netty 源码剖析MpscLinkedQueue 无锁多生产者单消费者队列的实现原理【免费下载链接】source-code-hunter 从源码层面剖析挖掘互联网行业主流技术的底层实现原理为广大开发者 “提升技术深度” 提供便利。目前开放 Spring 全家桶Mybatis、Netty、Dubbo 框架及 Redis、Tomcat 中间件等项目地址: https://gitcode.com/GitHub_Trending/so/source-code-hunter在 Netty 的核心组件 NioEventLoop 中任务队列 taskQueue 的实现正是 MpscLinkedQueue——一个基于多生产者单消费者MPSC模型的无锁队列。本文以 Netty 4.1.6 源码为基准从队列的头尾结点维护、offer() 无锁入队、remove() 限制到伪共享与内存屏障等实现细节逐层剖析它是如何在多生产者并发写入时不加锁也能保证线程安全的。MpscLinkedQueue 是什么在 EventLoop 组件 的解析中可以看到NioEventLoop 是 Netty 作为 Reactor 线程的核心成员它要承担两类工作通过聚合的 Selector 多路复用器处理网络 I/O 读写事件处理通过execute()提交到任务队列中的普通任务如定时任务、用户提交的 Runnable 等。当多个业务线程同时向同一个 NioEventLoop 提交任务时这个任务队列就必须是线程安全的。Netty 在这里选用的实现便是 MpscLinkedQueue多生产者Multi-Producer、单消费者Single-Consumer的无锁队列。之所以说它是“无锁”的关键在于 MPSC 的场景天然适配 NioEventLoop 的线程模型单消费者任务的消费始终只发生在 NioEventLoop 所属的这一个 I/O 线程内因此从队首取数据时根本不需要加锁多生产者任意业务线程都可能向队列尾部提交任务而 MpscLinkedQueue 最精妙之处正是在多生产者并发从尾部添加数据时同样没有加锁却依然保证了线程安全从而达成 Netty 所期望的高性能实现。这与 Netty 整体的无锁化串行设计一脉相承消息的处理尽可能在同一个 I/O 线程内串行完成避免多线程竞争与同步锁带来的性能损耗。下图展示了 Netty 基于该设计思想的串行化工作原理。MpscLinkedQueue 无锁并发线程安全写入原理通过继承 AtomicReference 维护尾结点首先MpscLinkedQueue 继承自AtomicReferencefinal class MpscLinkedQueueE extends AtomicReferenceMpscLinkedQueueNodeE implements QueueE { ... }也就是说MpscLinkedQueue 通过继承AtomicReference的方式显式地维护了一个提供原子读写能力的变量value。而在 MpscLinkedQueue 中这个value正是其内部维护的队列的尾结点。由于AtomicReference本身封装了基于UNSAFE的getAndSet()、lazySet()等原子操作尾结点的更新天然具备了原子性——这是整个无锁入队设计的基石。通过 FullyPaddedReference 维护头结点来看 MpscLinkedQueue 的构造方法MpscLinkedQueue() { MpscLinkedQueueNodeE tombstone new DefaultNodeE(null); headRef new FullyPaddedReferenceMpscLinkedQueueNodeE(); headRef.set(tombstone); setTail(tombstone); }在 MpscLinkedQueue 中维护着headRef头结点字段队列内部节点的实现是MpscLinkedQueueNode。这是一个除了存放具体队列元素外只有next字段的节点因此 MpscLinkedQueue 的队列是单向链表。构造方法中还做了一个关键动作创建了一个元素为 null 的DefaultNode作为“墓碑节点”tombstone同时将其设置给头结点和尾结点。也就是说空队列时头尾指向同一个节点setTail(tombstone)将继承自 AtomicReference 的尾结点字段value也设置为该节点。headRef的存在方便后续直接从头结点开始的队列操作——消费者可以简单地通过判断头尾节点是否相等来确认队列中是否有元素可以消费不需要额外的计数器或锁。offer() 如何做到线程安全的无锁加入offer()方法是整个无锁入队流程的核心源码如下Override SuppressWarnings(unchecked) public boolean offer(E value) { if (value null) { throw new NullPointerException(value); } final MpscLinkedQueueNodeE newTail; if (value instanceof MpscLinkedQueueNode) { newTail (MpscLinkedQueueNodeE) value; newTail.setNext(null); } else { newTail new DefaultNodeE(value); } MpscLinkedQueueNodeE oldTail replaceTail(newTail); oldTail.setNext(newTail); return true; } private MpscLinkedQueueNodeE replaceTail(MpscLinkedQueueNodeE node) { return getAndSet(node); }offer()方法很简短但恰恰就是整个元素入队的完整流程空值校验传入的value为 null 时直接抛出NullPointerException保证队列中不出现空元素节点封装判断加入的元素是否已经是MpscLinkedQueueNode如果是则直接复用该节点setNext(null)清空其后继引用如果不是则包装成新的DefaultNode原子换尾通过replaceTail()调用AtomicReference提供的getAndSet(node)将新节点原子地设置为队列尾结点并返回先前的尾结点oldTail。这次操作由UNSAFE的 CAS 保证原子性串联后继将之前的尾结点oldTail的next指向新加入的节点本次入队宣告结束。从整体上看MpscLinkedQueue 利用了AtomicReference底层UNSAFE的能力通过 CAS 确保新设置进value的节点必定能与原先的节点建立一个且唯一的联系那么只需要自顶向下不断把这个联系变成引用一条队列便形成了。由于实现是链表而不是数组也就不存在索引位置这类共享资源的竞争在不加锁的前提下其队列顺序可能不会严格遵循加入顺序但这对 NioEventLoop 任务队列的场景并不是问题任务之间彼此独立执行顺序并不敏感。归纳并发入队的过程在高并发的插入场景下每个新进入的节点都会通过 CAS 获取原尾位置value上的节点而自身会被设置为其后继节点并重新放到尾结点位置上。CAS 在不加锁的前提下保证了前后节点对应关系的唯一性——同一时刻只有一个生产者能成功getAndSet拿到旧尾结点其余生产者会拿到最新的尾结点继续串联因此并发条件下实现了不加锁的线程安全写入。MpscLinkedQueue 为什么不支持 remove()在 MpscLinkedQueue 中是不支持通过remove()方法从队列中移除任意一个元素的。原因很简单消费者和生产者都是无锁的。消费者可以通过比较队首和队尾元素是否一致来保证线程安全地从队首取数据poll()仅在头尾不同时才会推进头结点但remove()要从队列中任意位置修改数据这在无锁模型下是线程不安全的主要体现在如果移除的是队尾元素可能会导致正在加入的新元素被“丢弃”——例如生产者已通过 CAS 将新节点挂到旧尾结点之后而消费者/调用方却从中间把该节点摘除破坏了已建立起的链表引用关系。因此 Netty 在设计上直接放弃了remove()这类“任意位置删除”的操作以换取入队、出队的高性能无锁实现。MpscLinkedQueue 另外的实现细节除了核心的无锁入队逻辑MpscLinkedQueue 还有两个值得一提的性能优化细节头结点使用 FullyPaddedReference 避免伪共享MpscLinkedQueue 中的头节点headRef被通过FullyPaddedReference封装其内部在引用字段前后分别填充 56 字节和 64 字节使头结点对象占据一个完整的缓存行cache line从而避免**伪共享False Sharing**带来的性能损耗保证头结点可以被高效访问。在 MPSC 队列中头结点只被消费者NioEventLoop 线程读写尾结点却会被所有生产者线程并发写入。若头尾结点恰好落在同一个缓存行中消费者更新头结点时就会导致其他核上的生产者缓存行失效产生不必要的缓存同步开销。通过字节填充让头结点独占缓存行就规避了这种隐性的性能陷阱。消费时通过 UNSAFE 偏移量赋值头结点MpscLinkedQueue 在消费者消费数据后将下一个节点设置为头结点的时候并不是直接进行赋值而是通过UNSAFE根据内存偏移量来赋值。这样做可以略微提高性能主要是利用了内存屏障store-store和load-store之间的性能差异以更低的屏障开销完成头结点的推进。小结MpscLinkedQueue 是 Netty 为 NioEventLoop 任务队列量身定制的MPSC多生产者单消费者无锁队列其在 HashedWheelTimer 定时任务提交 等场景中同样通过 mpsc 队列模型借助 CAS 实现无锁提交入队时通过继承AtomicReference的getAndSet()原子换尾 旧尾结点next串联两步在无锁前提下保证了多生产者并发写入的线程安全出队时由唯一的消费者线程通过比较头尾节点判断队列是否为空天然免去了消费端的加锁出于无锁安全性的考虑队列不支持remove()任意位置删除通过FullyPaddedReference字节填充规避伪共享通过UNSAFE偏移量赋值降低内存屏障开销将性能优化到了极致。理解了 MpscLinkedQueue也就理解了 Netty 高性能背后“串行无锁化设计”的关键一环用数据结构特性 CAS 原子操作替代传统锁在保证线程安全的同时把并发竞争的成本降到最低。【免费下载链接】source-code-hunter 从源码层面剖析挖掘互联网行业主流技术的底层实现原理为广大开发者 “提升技术深度” 提供便利。目前开放 Spring 全家桶Mybatis、Netty、Dubbo 框架及 Redis、Tomcat 中间件等项目地址: https://gitcode.com/GitHub_Trending/so/source-code-hunter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号