Reputation: 2482
does offer blocks poll or vice versa ? meaning , can a producer offer and at the same time a consumer trying to poll ? or if a producer was offering , the queue blocks till he is done ?
object A
while (true){
inputQueue.offer(newPartList);
}
object B
while (true){
inputQueue.poll(newPartList);
}
Upvotes: 3
Views: 7625
Reputation: 1659
No, it does not. use LinkedBlockingDeque instead. Remember to use methods from BlockingDequeue or BlockingQueue interfaces to get values. as these methods are implemented as blocking.
Update
Neither offer
nor poll
methods are blocking. In linked interfaces only put*
and take*
methods are implemented as blocking. put
blocks as long as the queue is full, take
blocks if the queue is empty.
Now I see You are asking something else.
In LinkedBlockingDeque calling offer
blocks poll
, because this implementation has inernal Lock
for synchronizing access. In ConcurrentLinkedQueue's JavaDoc it is explicitly stated, that:
This implementation employs an efficient "wait-free" algorithm based on one described in
Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithmsby Maged M. Michael and Michael L. Scott.
which suggests that these operations don't block each other. If You are interested, I strongly suggest reading that paper for more insight.
Upvotes: 9
Reputation: 27190
Assuming you mean "thread A/B" when you say "object A/B".
Neither poll() nor offer() is a blocking method (Read the documentation for the Queue interface).
I don't understand the while(true)
loops in your example, but you appear to be asking what happens when you have an empty queue, and a data race between thread A, which calls q.offer(), and thread B, which calls q.poll().
Since you are asking about a ConcurrentLinkedQueue, the answer is simple: ConcurrentLinkedQueue is inherently thread-safe, which means there can be only two possible outcomes. Either thread A wins the race (i.e., the offer() "happens before" the poll()), or thread B wins the race (the poll() "happens before" the 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.
So, if A wins (the offer() happens before the poll()), then thread B will get the datum from the queue, and the queue will be left empty. If B wins (the poll() happens before the offer()), then thread B will get null (Again, read the doc for the Queue interface), and the datum will be left sitting in the queue.
Upvotes: 3
Reputation: 17422
It is not as simple as it seems to be. Actually acording to ConcurrentLinkedQueue
's javadoc, it follows a non-blocking algorithm:
"This implementation employs an efficient non-blocking 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."
If you are curious enough and have a look at the source code, you'll see something like this:
/**
* 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;
}
}
The comments from the source code suggest a rather try-error aproach than a secured-synchronized one.
Upvotes: 2