Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrently iterating over a BlockingQueue

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.

like image 995
emu Avatar asked Feb 07 '23 17:02

emu


1 Answers

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.

like image 107
Stephen C Avatar answered Feb 09 '23 07:02

Stephen C