In an application which uses a BlockingQueue
, I am facing a new requirement that can only be implemented by iterating over the elements present in the queue (to provide info about the current status of the elements in there).
According to the API Javadoc
only the queueing methods of a BlockingQueue implementation are required to be thread-safe. Other API methods
(eg. those inherited from the Collection interface
) may not be used concurrently, though I am not sure whether this also applies to mere read access...
Can I safely use iterator() WITHOUT altering the producer/consumer threads
which may normally interact with the queue at any time? I have no need for a 100% consistent iteration
(it does not matter whether I see elements added/removed while iterating the queue), but I don't want to end up with nasty ConcurrentModificationExceptions
.
Note that the application is currently using a LinkedBlockingQueue
, but I am free to choose any other (unbounded) BlockingQueue implementation
(including free open-source third-party implementations
). Also, I don't want to rely on things that may break in the future, so I want a solution that is OK according to the API
and does not just merely happen to work with the current JRE
.
Actually, the Java 8 javadoc for BlockingQueue
states this:
BlockingQueue
implementations are thread-safe.
Nothing in the javadoc says1 that this only applies to the methods specified in the BlockingQueue
API itself.
Can I safely use iterator() WITHOUT altering the producer/consumer threads which may normally interact with the queue at any time?
Basically, yes. The Iterator
's behavior in the face of concurrent modifications is specified in the implementation class javadocs. For LinkedBlockingQueue
, the javadoc specifies that the Iterator
returned by iterator()
is weakly consistent. That means (for example) that your application won't get a ConcurrentModificationException
if the queue is modified while it is iterating, but the iteration is not guaranteed to see all queue entries.
1 - The javadoc mentions that the bulk operations may be non-atomic, but non-atomic does not mean non-thread-safe. What it means here is that some other thread may observe the queue in state where some entries have been added (or removed, or whatever) and others haven't.
@John Vint warns:
Keep in mind, this is as of Java 8 and can change.
If Oracle decided to alter the behavior specified in the javadoc, that would be an impediment to migration. Past history shows that Sun / Oracle avoid doing that kind of thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With