我的线程永远运行并在ConcurrentLinkedQueue#peek()之后调用ConcurrentLinkedQueue#poll()。
但在某些情况下,线程似乎挂了。我知道这有点模糊 但是人们可以向我确认方法poll()或peek()将从不阻止。感谢。
答案 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()将阻塞,直到他们可以确定队列是否为空。
但除非你使用一些非常奇怪的线程优先级,否则这种情况不太可能高度,我建议你到别处寻找你的错误。