Search code examples
javaconcurrencyblockingqueue

How to block until a BlockingQueue is empty?


I'm looking for a way to block until a BlockingQueue is empty.

I know that, in a multithreaded environment, as long as there are producers putting items into the BlockingQueue, there can be situations in which the queue becomes empty and a few nanoseconds later it is full of items.

But, if there's only one producer, then it may want to wait (and block) until the queue is empty after it has stopped putting items into the queue.

Java/Pseudocode:

// Producer code
BlockingQueue queue = new BlockingQueue();

while (having some tasks to do) {
    queue.put(task);
}

queue.waitUntilEmpty(); // <-- how to do this?

print("Done");

Do you have any idea?

EDIT: I know that wrapping BlockingQueue and using an extra condition would do the trick, I'm just asking if there are some pre-made solutions and/or better alternatives.


Solution

  • A simple solution using wait() and notify():

    // Producer:
    
    // `sychronized` is necessary, otherwise `.notify` will not work
    synchronized(queue) {
        while (!queue.isEmpty())
            queue.wait(); // wait for the queue to become empty
            // this is not a deadlock, because `.wait` will release the lock
        queue.put();
    }
    
    // Consumer:
    synchronized(queue) {
        queue.get();
        if (queue.isEmpty())
            queue.notify(); // notify the producer
    }