Why the Thread Executer itself is still in memory after being shutdown?
Using Java and App Server I deploy application that has a thread executer.
During un-deploy I request the executer to shutdown. This successfully cancels all the tasks. However via VisualVM I can still see a thread that represents the executer itself and it is in the wait sate. I don't keep any references to the executer as the whole application get undeployed. So if i repeat the deployment-undeployment cycle multiple times I can see how the threads number grows.
How do I get rid of them?
UPDATE:
code example
here is the code:
public void startScheduler()
{
if (scheduledExecutor == null)
{
scheduledExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("My ScheduledExecutor"));
processFuture = scheduledExecutor.scheduleAtFixedRate(new Runnable()
{
@Override
public void run()
{
startProcessor();
}
}, 0, 84600, TimeUnit.SECONDS);
}
}
public void stopScheduler()
{
开发者_运维技巧if (processFuture != null)
{
processFuture.cancel(true);
processFuture = null;
}
if (scheduledExecutor != null)
{
try
{
scheduledExecutor.shutdownNow();
scheduledExecutor.awaitTermination(10, TimeUnit.SECONDS);
}
catch (InterruptedException ignored)
{}
finally
{
scheduledExecutor = null;
}
}
}
Could you please elaborate what you mean with "a thread that represents the executer itself". What is it's name/id/threadgroup? I don't think executor service creates such a thread.
Executors create new threads (using the configurable ThreadFactory). A Thread automatically inherits some properties of its parent, that is the Thread.currentThread(). The most problematic part of this behavior in a web application scenario with deploy/undeploy cycles however is the Thread's ContextClassLoader, which is inherited from the parent's thread. If your ContextClassLoader holds on to classes from within your web application archive, then the spawned Executors Thread will also have a reference to this ClassLoader. If the code which is executed by the Executor has e.g. ThreadLocals with classes from the WebappClassLoader, you may experience a ClassLoader leak problem.
The Executor needs to be stopped explicitly, using the method shutdown, otherwise it will hang around like you have found out. You can see from the javadoc for Executors.newSingleThreadExecutor that it includes a worker thread.
The javadoc for shutdownNow says:
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so if any tasks mask or fail to respond to interrupts, they may never terminate.
If the task being executed doesn't respond to interrupts (swallows InterruptedExceptions without ever exiting), then that would cause your executor to never get shutdown. Any non-daemon threads that don't get shutdown explicitly will hang around and keep the JVM from exiting. That can be a fun one to debug.
精彩评论