ConcurrentLinkedQueue 的大小

发布于 2024-08-31 00:10:31 字数 527 浏览 2 评论 0原文

阅读 Java 的 ConcurrentLinkedQueue 文档,我想知道为什么实现不可能存储大小:

请注意,与大多数集合不同,大小方法不是恒定时间操作。由于这些队列的异步特性,确定当前元素数量需要遍历元素。

这种“异步性质”在中的什么地方? 我只看到一个 while 循环来重试排队,直到 AtomicReferences 匹配预期值/引用。为什么在成功向队列提供值后无法增加 size:AtomicInteger

多谢。

Reading Java's ConcurrentLinkedQueue Docs, I wonder why it is not possible for the implementation to store the size:

Beware that, unlike in most collections, the size method is NOT a constant-time operation. Because of the asynchronous nature of these queues, determining the current number of elements requires a traversal of the elements.

Where in the source is this "asynchronous nature"?
I only see a while-loop to retry enqueing until the AtomicReferences match the expected values/references. Why is it not possible to increment an size:AtomicInteger after successfully offering a value to the Queue?

Thanks alot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ぽ尐不点ル 2024-09-07 00:10:31

假设您有两个线程,一个添加新项目,另一个删除项目。开始时队列中没有项目。

假设第一个线程添加了该项目,紧接着另一个线程删除了该项目并减小了大小,此时您的大小为 -1,然后第一个线程将大小增加到 0。这是

一个稍微做作的示例,但您会需要使整个操作原子化,以确保没有其他线程可以访问-1的大小。

Imagine you have two threads, one adding a new item, and the other deleting an item. There are no items in the queue at the start.

Suppose the first thread adds the item, immediately followed by the other thread removing the item and decrementing the size, at which point your size is at -1, then the first thread increments the size to 0.

A slightly contrived example, but you would need to make the whole operation atomic in order to ensure that no other threads could get access to the size of -1.

倾城泪 2024-09-07 00:10:31

ConcurrentLinkedQueue 的重要性能优势之一来自于这样一个事实:更新头部时您不必担心尾部,反之亦然,对吗?

这基本上意味着 2 个线程可以同时轮询/提供而不会发生干扰(即,如果队列大小不为 0)。

如果你有一个柜台,情况就不是这样了。即使它是一个具有良好并发性的 AtomicInteger,您仍然会增加 CAS 操作失败的可能性,因为现在您有了这个“热点”,每次进行 poll/offer 时都会更新它。

不完全确定作者在说“异步性质”时是否是这个意思,但我认为这是他们没有像您建议的那样的计数器的最大原因。

One of the important performance benefit of ConcurrentLinkedQueue comes from the fact that you don't worry about the tail when you update the head, and vice versa, right?

This means basically that 2 threads can poll/offer at the same time without interfering (if the queue size wasn't 0, that is).

This weren't the case if you had a counter. Even if it was a AtomicInteger which has good concurrency, you will still have increased possibility of having failed CAS operations because now you have this "hot spot" that you update every time you do poll/offer.

Not entirely sure if the authors mean this when they say "asynchronous nature", but I think this is the biggest reason they don't have a counter like you suggested.

指尖微凉心微凉 2024-09-07 00:10:31

为什么不能增加
成功后大小:AtomicInteger
向队列提供值?

可能是因为该提供/递减无法以原子方式完成,而不会对方法的并发性产生不利影响。

Why is it not possible to increment an
size:AtomicInteger after successfully
offering a value to the Queue?

Probably because that offer/decrement could not be done atomically without adversely affecting the concurrency of the method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文