This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
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


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
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
Author

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 (http://www.javafaq.nu/java-example-code-969.html) 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?

-=beeky
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4167
    
  21

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:


Steve
William Stafford
Ranch Hand

Joined: Dec 13, 2004
Posts: 109
Steve,
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,
-=beeky
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: What could still be running after threads return?
 
Similar Threads
Doug Lea PooledExecutor won't grow larger than minimumPoolSize
Some questions!!!
Deamon Thread Sample
join() in thread...continues....
ScheduledExecutorService - Time To Live