Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

ServletContextListener (contextDestroyed) with Threads

 
Andreas Markitanis
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys,

When the contextDestroyed() method is called, I am using a method whose task is to stop all threads safely. However, this takes approximately 5-6 seconds, and when the server is either restarted or the application is removed I get warnings about possible memory leaks. I have debugged the program, and when I stepped over the method which stops all the threads, and wait for a bit, the threads are eventually removed ( I can verify this using JConsole) and hence no errors about possible memory leaks
( SEVERE: A web application appears to have started a thread named [...] but has failed to stop it )

I tried Thread.sleep which seems to be doing the job...but I have to specify the time...

Is there a nicer solution/workaround for this? Perhaps one that does not require a time variable?

Thanks
 
Andreas Markitanis
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
anyone?
 
ramprasad madathil
Ranch Hand
Posts: 489
Eclipse IDE Java Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When the contextDestroyed() method is called, I am using a method whose task is to stop all threads safely.


Which threads? The server or any that your application spawns?

ram.
 
Andreas Markitanis
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Other ones that my app spawns.

Thanks
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 64830
86
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Perhaps this might fare better in the threading forum. I'll move it there and we'll see.
 
Steve Luke
Bartender
Posts: 4181
21
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One solution would be to use an ExecutorService to launch the threads, then when it is time to shutdown you tell the ExecutorService to shutdown(), then use and combination of isTerminated() and awaitTermination(time,units) to determine when all the threads are dead.

You could probably do something similar if you generate your Threads using a single ThreadGroup, then loop a wait/sleep step until the ThreadGroup's activeCount() reaches zero.

Finally, you could have a 'listener' type protocol. Wrap all your tasks in a Runnable. The first thing the run() method does is register itself in some listener, and the last thing it does is tell the listener it is complete. Your contextDestroyed would then wait on the listener to report that all the Threads that have been registered have completed. This isn't any different, really, than the ExecutorService strategy, except you need Java 1.5+ to use Executors, so if your servlet container doesn't yet use Java 1.5 you would need to 'roll your own.'
 
Andreas Markitanis
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve, thanks for your replies.

I forgot to mention that I don't have control over those threads. They're being started by a library I have to use and therefore the solutions you provided me with I cannot use, unless there's still a workaround which I might be missing.

Thanks

 
Steve Luke
Bartender
Posts: 4181
21
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Andreas Markitanis wrote:Steve, thanks for your replies.

I forgot to mention that I don't have control over those threads. They're being started by a library I have to use and therefore the solutions you provided me with I cannot use, unless there's still a workaround which I might be missing.

Thanks



Well, I guess it depends on what control the library provides you with, and how you interact with the Threads. Do you provide tasks that get executed in the Library? If so than the third option ('roll your own') would work. If the Library allows you to provide a ThreadFactory from which it generates the Threads it uses, then you could use the second option (ThreadGroup - ie you could provide it with a ThreadFactory which generates Threads from a specific ThreadGroup. As an addendum to this, unless the Library specifically generates its Threads in its own groups, the default behavior is to generate new Threads in the same Group as the creating Thread. So you could spawn a dummy Thread from a ThreadGroup you control and use it to call the Library methods which generate new Threads to get same effect). If the Library allows you to query it for count of tasks which are running then you can do some modified version of the first option.

If you can't find any of the above then you have to be a little more creative about what information the Library leaks out, like perhaps scanning all running Threads for ones with specific names/name patterns. This tends to be fragile though since those names could be changed or used by other services... they don't generally constitute part of the Libraries API.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic