• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

What could still be running after threads return?

 
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 109
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
reply
    Bookmark Topic Watch Topic
  • New Topic