确实提供了块调查,反之亦然?意思是,生产者可以提供并同时消费者试图进行民意调查吗?或者如果一个制作人提供,队列会阻塞直到他完成?
对象A
while (true){
inputQueue.offer(newPartList);
}
对象B
while (true){
inputQueue.poll(newPartList);
}
答案 0 :(得分:6)
不,它没有。请改用LinkedBlockingDeque。请记住使用BlockingDequeue或BlockingQueue接口中的方法来获取值。因为这些方法被实现为阻止。
<强>更新强>
offer
和poll
方法都没有阻止。在链接接口中,只有put*
和take*
方法被实现为阻塞。只要队列已满,put
就会阻塞,take
会阻塞队列为空。
现在我看到你在问别的什么。
在LinkedBlockingDeque调用offer
块poll
,因为此实现具有用于同步访问的inernal Lock
。在ConcurrentLinkedQueue's JavaDoc中明确声明:
This implementation employs an efficient "wait-free" algorithm based on one described in
Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms by Maged M. Michael and Michael L. Scott.
表明这些操作不会相互阻挡。如果您有兴趣,我强烈建议阅读该论文以获得更多见解。
答案 1 :(得分:3)
当您说“对象A / B”时,假设您的意思是“线程A / B”。
poll()和offer()都不是阻塞方法(阅读Queue接口的文档)。
我不理解你的示例中的while(true)
循环,但是你似乎在询问当你有一个空队列时会发生什么,以及在线程A之间的数据竞争调用q.offer()和调用q.poll()。
由于您询问的是ConcurrentLinkedQueue,答案很简单:ConcurrentLinkedQueue本质上是线程安全的,这意味着只有两种可能的结果。线程A赢得比赛(即,offer()“发生在”poll()之前),或者线程B赢得比赛(poll()“发生在”offer()之前)。
There is no such thing as "at the same time." In the case of ConcurrentLinkedQueue,
"thread safe" means that no matter how close the race, there will always be a winner
and a loser.
因此,如果A获胜(offer()发生在poll()之前),则线程B将从队列中获取数据,并且队列将保留为空。如果B获胜(poll()发生在offer()之前),则线程B将变为null(再次,读取Queue接口的doc),并且数据将保留在队列中。
答案 2 :(得分:2)
它并不像看起来那么简单。实际上根据ConcurrentLinkedQueue
的javadoc,它遵循非阻塞算法:
“此实现采用了一种有效的非阻塞算法,该算法基于Maged M. Michael和Michael L. Scott在简单,快速,实用的非阻塞和阻塞并发队列算法中所描述的算法。”
如果您有足够的好奇并查看源代码,您会看到类似的内容:
/**
* Inserts the specified element at the tail of this queue.
* As the queue is unbounded, this method will never return {@code false}.
*
* @return {@code true} (as specified by {@link Queue#offer})
* @throws NullPointerException if the specified element is null
*/
public boolean offer(E e) {
checkNotNull(e);
final Node<E> newNode = new Node<E>(e);
for (Node<E> t = tail, p = t;;) {
Node<E> q = p.next;
if (q == null) {
// p is last node
if (p.casNext(null, newNode)) {
// Successful CAS is the linearization point
// for e to become an element of this queue,
// and for newNode to become "live".
if (p != t) // hop two nodes at a time
casTail(t, newNode); // Failure is OK.
return true;
}
// Lost CAS race to another thread; re-read next
}
else if (p == q)
// We have fallen off list. If tail is unchanged, it
// will also be off-list, in which case we need to
// jump to head, from which all live nodes are always
// reachable. Else the new tail is a better bet.
p = (t != (t = tail)) ? t : head;
else
// Check for tail updates after two hops.
p = (p != t && t != (t = tail)) ? t : q;
}
}
源代码中的注释表明了一种相当于尝试错误的方法,而不是安全同步方式。