ConcurrentLinkedQueue的大小

时间:2010-05-03 15:00:49

标签: java size queue concurrency

阅读Java's ConcurrentLinkedQueue Docs,我想知道为什么实现不可能存储大小:

  

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

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

非常感谢。

3 个答案:

答案 0 :(得分:5)

想象一下,你有两个线程,一个添加一个新项目,另一个删除一个项目。开始时队列中没有任何项目。

假设第一个线程添加项目,紧接着另一个线程删除项目并递减大小,此时大小为-1,然后第一个线程将大小增加到0.

一个有点人为的例子,但你需要使整个操作成为原子,以确保没有其他线程可以访问-1的大小。

答案 1 :(得分:4)

ConcurrentLinkedQueue的一个重要性能优势来自于您在更新头部时不担心尾部,反之亦然,对吧?

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

如果你有一个柜台,情况并非如此。即使它是一个具有良好并发性的AtomicInteger,你仍然会增加CAS操作失败的可能性,因为现在你有这个“热点”,你每次轮询/提供时都会更新。

当作者说“异步性质”时,并不完全确定作者是否意味着这一点,但我认为这是他们没有像你建议的那样的反击的最大原因。

答案 2 :(得分:0)

  

为什么无法增加   size:AtomicInteger成功后   为队列提供一个值?

可能是因为在不对方法的并发性产生负面影响的情况下,无法以原子方式完成提供/减少。