← 每日面试题 学习看板

如何借鉴 Disruptor 的 RingBuffer 思想设计一个低延迟的无锁并发队列?

面试题/00java/02Java 并发编程/02JUC工具类/如何借鉴 Disruptor 的 RingBuffer 思想设计一个低延迟的无锁并发队列?.md

面试记录 2026-10-17

题目:如何借鉴 Disruptor 的 RingBuffer 思想设计一个低延迟的无锁并发队列?

难度:high

标签:java/juc, java/concurrency, general/knowledge

评分:⭐⭐☆☆☆(2/5)

我的回答

通过环形数组,来实预创建空间,通过序号实现不同索引位置的读取,使用cas不用锁来实现序号更新;去读取数组内的内容,他没有锁,使用序号可以快速读取目标位置内容实现低延迟,高内存利用,而不是像是链表读取内容还需要遍历

点评

优点:抓住"环形数组 + 预分配 + 序号 + CAS 无锁"这四个关键点,方向对。

不足:缺了低延迟的灵魂——生产者/消费者序号协调。只说了"用序号读",没说多个生产者的序号怎么 CAS 竞争、消费者怎么通过 Sequence/SequenceBarrier 判断可消费位置、如何避免覆盖未消费数据。

补充:还有两个关键点没提——缓存行填充(padding)消除伪共享、预分配对象避免 GC;以及 Disruptor 用"批处理 + 序号依赖"做到无锁且高吞吐。

完整讲解

第一部分:知识重点剖析

核心考点定位:能否讲清 RingBuffer 的无锁协调机制(序号)与低延迟手段(防伪共享、无 GC)。

知识点拆解:

  1. 环形数组 + 预分配:容量为 2 的幂,取模用位运算 index & (size-1);元素在启动时全部预创建,运行期不再 new,避免 GC 抖动。
  2. 序号(Sequence)协调:
  1. 消除伪共享:对序号字段做缓存行填充(padding 到 64 字节),避免相邻字段互相失效缓存行。
  2. 批处理:一次拿到连续可用区间,减少 CAS 和等待次数,提升吞吐。

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. Disruptor 为什么比 BlockingQueue 快?
  1. 多生产者如何避免序号冲突?
  1. 为什么环形容量要取 2 的幂?

第三部分:面试者参考回答(三步法口语化)

【一句话结论】

面试官您好,RingBuffer 的核心是"环形数组 + 序号协调 + 无锁",本质是用序号代替锁来协调生产消费。

【三点展开】

第一,空间预分配:容量取 2 的幂,启动时把元素全部创建好,取模用位运算,运行期零 GC;

第二,序号协调是无锁的关键:生产者用 CAS 抢占写序号,消费者用 SequenceBarrier 按依赖等待可读序号,靠"序号差 ≥ 容量"判断能否覆盖;

第三,低延迟的细节:序号字段做缓存行填充消除伪共享,再靠批处理一次取连续区间,减少 CAS 和等待。

【一句边界】

当然,Disruptor 适合吞吐极高、依赖简单的场景;如果只是普通异步解耦,BlockingQueue 更简单够用。