ConcurrentLinkedQueue#poll()会阻塞吗?

时间:2009-02-19 11:42:11

标签: java concurrency

我的线程永远运行并在ConcurrentLinkedQueue#peek()之后调用ConcurrentLinkedQueue#poll()。

但在某些情况下,线程似乎挂了。我知道这有点模糊 但是人们可以向我确认方法poll()或peek()将从不阻止。感谢。

3 个答案:

答案 0 :(得分:2)

据我所知,ConcurrentLinkedQueue是一个“无需等待”的实现。

所以我必须假设每次对poll()peek()的独立通话都永远不会阻止

此集合上的原子操作是同步的,并且每个单独的队列调用都保证是线程安全的。

您的代码一定有问题。例如,如果你这样做:

Object obj;

if (queue.peek() != null)
   obj = queue.poll()

不保证obj不会null

答案 1 :(得分:0)

根据Javadoc,似乎peek()和poll()不应该阻塞。我掀起了一个快速的生产者/消费者测试,我没有阻止。

答案 2 :(得分:0)

我不相信你的问题是由于这个,但poll()和peek()可以(至少在理论上)阻止:

顾名思义,ConcurrentLinkedQueue是作为链表实现的。轮询或窥视时,实现尝试从头开始并遍历链接节点,尝试查找未删除的节点。如果它找到非空节点,则返回该节点,如果它到达结尾,则返回队列为空,但如果找到已删除的节点,则重试。

所以考虑这个顺序。 P是生产者线程,我们有两个消费者线程C1和C2:

P:  queue.add()
C1: starts queue.poll(), begins to inspect first node
C2: completes a queue.poll() removing the item.
P:  queue.add()
C1: continues inspecting the first node, notes that it is deleted. 
      Restarts and begins to inspect the new first node.
C2: completes a queue.poll() removing the item.
P:  queue.add()
C1: continues inspecting the first node, notes that it is deleted. 
      Restarts and begins to inspect the new first node.
etc.

所以poll()和peek()将阻塞,直到他们可以确定队列是否为空。

但除非你使用一些非常奇怪的线程优先级,否则这种情况不太可能高度,我建议你到别处寻找你的错误。