2
votes

For a single producer-consumer arrangement the producer places a 'done signal' as the last item on the queue. The consumer checks each object taken from the queue and shuts down when the done signal is dequeued.

while(true) {
    MyQueueableObject o = queue.take() ;
    if ( o.type==PRODUCER_DONE_SIGNAL ) {
        return() ;
    }
    process ( o ) ;
}

However, this only works for a single producer-consumer. Because the BlockingQueue will block the take() call until there is something on the queue, it seems to me that in a multiple consumer design there should be another nested loop that checks on some stopping condition.

while(true) {
    while ( ... stop condition not detected ... ) {
        process ( queue.take()  ) ;
    }
    return ;
}

I have thought about this at length and all of the stop conditions I can come up with involve the state of the producer threads and the state of the queue. Both seem unnecessarily complicated and error prone. Even worse, this approach seems like a time bomb. A consumer thread could be interrupted after checking the stop condition and getting false and before trying to take something from the queue. During that interruption the other consumers could have emptied the queue. In that case the queue will block the thread forever.

How do you fashion a stop condition for multiple consumers using a Java 1.5 BlockingQueue ?

2

2 Answers

2
votes

Upon reading the PRODUCER_DONE_SIGNAL each consumer could add it back onto the queue again for the next consumer to take. However, I would also consider using a condition external to the queue (e.g. Condition object): That way you can terminate the threads early even if the queue still contains empty (for example if you wished to shut down immediately).

0
votes

What about feeding PRODUCER_DONE_SIGNAL multiple number of times, equal to the number of producers?