[concurrency-interest] how to auto-terminate producer-consumer service

Timo Nentwig concurrency-interest at nitwit.de
Tue Mar 27 12:16:51 EDT 2007


This is about chapter 7.2 in jcip but I don't want to shutdown or cancel the 
service but merely there's finite amount of work to do and when it's done the 
service is supposed to shutdown itself.

So Nproducer threads and Nconsumer thread connected via a BlockingQueue. The 
problem: when the producers have done their job how do the consumer know? And 
even if they would know they would be blocked in take() anyway.

One solution is presented in 7.2.2 but I waiting until the producers are done 
and then interupting the consumers just to tell them to finished their work 
and then shutdown would be reallly weird coding.

7.2.3 suggest a poison pill. This is actually what I did but I'm not happy 
with it. If each producer puts a single poison pill into the queue it will 
only work if Nproducer>=Nconsumer. Letting each producer put Nconsumer poison 
pills in the queue will only work for Nproducer==1 otherwise all consumers 
will  be dead by the time other producers are still producing. And finally 
IMHO it's bad design that the producer are coupled to the consumer by having 
to know what many consumers are actually out there.

So came up with the idea that not the producers are putting the poison pills 
into the queue but actually the thread that started the producers and 
consumers:

			// start producers and consumers

			// wait until producers are finished
			for( final Thread t : producers )
                                t.join();

			// put Nconsumer poison pill in the queue, put() will block
                        for( int i = 0; i < consumers.length; i++ )
                                queue.put( POISON_PILL );

			// and finally wait for the consumers to swallow the poison pill
                        for( final Thread i : consumers )
                                i.join();

(I yet didn't have had a closer look at the new Executer stuff :-)

This works. But I don't like it. The consumers could peek() before take() and 
watch out for poison pills but I would have to lock the queue for this case 
and that's not worth it.

Isn't there a better solution? Some Queue with poison pilll functionality 
comes to my mind but it will be somewhat tricky how to handle multiple 
producers...


More information about the Concurrency-interest mailing list