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 ?