So digging through the bowels of the Java 6 source (skip the part between the horizontal rules if you don't care about finding the actual code responsible for this stuff)
The class
java.util.concurrent.LinkedBlockingQueue
implements mutex using instances of
java.util.concurrent.locks.ReentrantLock
.
In turn, synchronization variables are generated using java.util.concurrent.locks.ReentrantLock.newCondition()
which calls java.util.concurrent.locks.ReentrantLock$Sync.newCondition()
.
The method java.util.concurrent.locks.ReentrantLock$Sync.newCondition()
returns an instance of java.util.concurrent.AbstractQueuedSynchronizer$ConditionObject
which implements the normal synchronization variable calls to await()
, signal()
and signalAll()
described by the interface java.util.concurrent.locks.Condiion
.
Looking at the source code for the ConditionObject
class, it keeps two members called firstWaiter
and lastWaiter
that are the first and last nodes in a CLH lock queue (instances of java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
).
The documentation in that class states:
A thread may try to acquire if it is first in the queue. But being first does not guarantee success; it only gives the right to contend. So the currently released contender thread may need to rewait.
So I believe the answer here is that the take()
method in LinkedBlockingQueue
attempts to give preferential treatment to those thread which called take()
earlier. It will give the first thread to call take()
the first chance to grab a queue item when it becomes available, but due to timeouts, interrupts, etc. that thread is not guaranteed to be the first thread to get the item off of the queue.
Keep in mind that this is completely specific to this particular implementation. In general you should assume that calls to take()
will wake up a random waiting thread when a queue item becomes available and not necessarily the first one that called take()
.