【问题标题】:Is there a bounded lock-free blocking queue?是否存在有界无锁阻塞队列?
【发布时间】:2026-01-31 03:25:01
【问题描述】:

目前我们有 LinkedBlockingQueue 和 ConcurrentLinkedQueue。

LinkedBlockingQueue 可以有界,但它使用锁。

ConcurrentLinkedQueue 不使用锁,但它没有限制。而且它不会阻塞,这使得投票变得困难。

显然,我不能有一个既阻塞又无锁(无等待或非阻塞或其他)的队列。我不要求学术定义。

有谁知道队列实现主要是无锁(不在热路径中使用锁)、空时阻塞(无需忙于等待)和有界(满时阻塞)?也欢迎非堆解决方案。

我听说过 LMAX Disruptor,但它看起来一点也不像队列。

我也很高兴知道非通用解决方案(Single-Producer-Single-Consumer、SPMC、MPSC)

如果没有已知的实现,我也很高兴知道可能的算法。

【问题讨论】:

  • 如果您描述了您的问题域,它可能会使这个问题更加“不可关闭”。现在你只是在寻求外部资源。
  • JDK 没有提供这样的队列实现:(1) 大部分是无锁的,(2) 不需要忙等待,(3) 有界。 LinkedBlockingQueue 和 ArrayBlockingQueue 满足(2)和(3),ConcurrentLinkedQueue 只满足(1)。而我想要的是一个能够满足所有这些需求的队列。如果没有实现,也欢迎提供算法描述。按照LMAX的说法,disruptor ring buffer似乎满足了一切,但它看起来不像队列,相信底层算法可能很难实现队列。
  • 我的意思是解释一下您正在使用哪种域。您的问题中明确了对性能队列的要求。至于 LMAX 破坏者,您需要以更广泛的方式将其整合到您的架构中。毕竟,它不是 Queue 的直接替代品。
  • 我在问一个非常具体的问题。即具有某些活性属性的队列。就像,是否可以问,是否可以在 O(n) 中对列表进行排序,或者是否有可以在 O(n) 中对列表进行排序并且易于使用的库。我说必须有一个吗?如果你知道有一个,那么这个问题并不是没有用的,因为我们知道我们可以做一些事情。如果你知道不可能(即自相矛盾),那就证明吧,这个问题也不是没用的,因为现在我们知道我们不能做某事。
  • 您要求外部资源,这是关闭问题的基础之一(如果您看不到,目前有 3 个关闭投票)。您还让以否定的方式回答这个问题变得非常不可能,因为“不,没有这样的队列”将是一个相当大胆的声明。你不能接受你问了一个不好的问题并继续前进吗?如果我处于你的位置,我会在网上搜索,而不是在 SO 上进行一对一的交流。注意:您可以问“是否可以在 O(n) 中排序”,但要求图书馆这样做是题外话。

标签: java concurrency


【解决方案1】:

无锁数据结构使用原子读写(例如compare-and-swap)来消除对锁的需求。自然,这些数据结构永远不会阻塞。

您描述的是一个使用无锁机制进行非阻塞调用的队列,例如remove() 具有非空队列,同时使用锁来阻塞例如remove() 在空队列中。

您可能会意识到这是不可能实现的。例如,如果您要在弹出操作之后查看队列是否实际上是空的,然后继续阻塞,当您阻塞时,队列可能已经有一个或多个由另一个线程插入的项目。

【讨论】:

  • 是的,我认为如果队列中剩下(接近)0 个项目,线程可以阻塞是完全合理的,并且当队列(接近)满时显然同样适用。我只是不认为 FAST PATH 上必须有任何潜在的阻塞操作。还是确实有一些不可能的原因?比如Single Producer Single Consumer的情况下,也许生产者和消费者可以更新自己的指针,互不影响(在快速路径中)?