File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
The moose likes Threads and Synchronization and the fly likes What could still be running after threads return? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "What could still be running after threads return?" Watch "What could still be running after threads return?" New topic

What could still be running after threads return?

William Stafford
Ranch Hand

Joined: Dec 13, 2004
Posts: 109
I'm running Ian Darwins producer-consumer for Java 1.5 example ( from Eclipse Ganymede. I added some output immediately before the threads return statements to assure myself that the return was being reached when the stop signal was sent. I see that all threads have reached their return. Using the windows task manager I can see a javaw.exe process start when I start my app and this process is still shown after the last line of my main has been executed. So something is still running when the main exits.

Is this thread related or Eclipse related?

Steve Luke

Joined: Jan 28, 2003
Posts: 4181

It looks to me like any consumer which reaches the take() step before the done flag is set will sit and wait for an object to be available and will never actually see that done flag being set. This probably comes up regularly if the consumer is much faster than the producer, or there are fewer producers than consumers.

The fixes I can think of:
1) Make Consumer threads Daemons, so any Consumers waiting in the take() method will die when the application ends. This works, but I generally like to explicitly end Threads when I can, so I avoid this one (I consider it a bit of a hack)

2) When the done flag is set, also interrupt your consumers (and producers as well) so they are forced to see the done flag. My preference, when I use this method, is to (a) not use while(true) but instead use while(!done). (b) Put the catch for the InterruptedException INSIDE the while loop. We will catch interrupted exceptions but maybe that shouldn't kill the thread.

3) You could use a poison pill approach. The problem here is caused by the fact that the Consumer is sitting in a take() statement and there is nothing to take(). So you could make the producer give consumers a sign that the queue is complete, take this poison and die. This is especially useful if you want the Consumers to finish any backlog of objects in the queue before they die (if there is a backlog, they can keep churning through the list until they reach poison). To make it work you need a fixed object that the Producer can supply and the Consumer can recognize as a signal to end. When the Producer gets the done flag, it puts the signal into the queue and then comes to an end itself. Note that you may have multiple producers and so may have multiple poison signals, that is okay. Then the Consumer churns through the queue and gets to a Poison object, recognizes it and dies. I usually make it add the poison back to the queue in case there are more Consumers than Producers to make sure all Consumers get a Poison pill. Something like this:

William Stafford
Ranch Hand

Joined: Dec 13, 2004
Posts: 109
Thanks for the great reply! You were right on the money, the consumer was so much faster than the producer that it ended up just sitting on the empty queue. Following your explanation I had the producer put a signal object on the queue before exiting, problem solved.

Thanks again for the great explanation of what was involved,
I agree. Here's the link:
subject: What could still be running after threads return?
It's not a secret anymore!