Shutting down a TaskExecutor in a web application when the web server is shutdown
I have a web application that makes use of a Spring TaskExecutor. The task executor is started when the web application is loaded for the first time and the thread runs the entire life of the web application. Ever since I added this thread to the application, Oracle Application Server will no longer shutdown gracefully. My guess is that OAS is not shutting down because I am not gracefully shutting down the task executor thread anywhere in the code. Where would the best place be to shutdown the task executor in a web application? I am using Java 5 with Spring 2.5.6.
Here is th开发者_JAVA百科e task executor that I am using:
<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
SimpleAsyncTaskExecutor
has no meaningful state, it does not require shutting down gracefully. Also, I'm not sure what you mean by "the thread runs the entire life of the web application" - which thread are you referring to?
However, the threads that it spawns may be preventing your server from shutting down. SimpleAsyncTaskExecutor
uses a ThreadFactory
to create its threads, and by default threads that are created are not daemon threads, and so any spawned threads which are still executing when the shutdown is initiated will continue, and the server will only terminate when all of those spawned threads are finished.
As a solution, I suggest using a ThreadPoolTaskExecutor
in preference to the SimpleAsyncTaskExecutor
. This has a boolean property which controls what happens when a shutdown occurs, and it can force the termination of the thread pool if required.
If you still want to use SimpleAsyncTaskExecutor
, then you could inject it with a custom ThreadFactory
which creates deamon threads. This will allow the server to shutdown regardless of the state of those spawned threads. This might be dangerous, though, if those threads could leave resources in an unstable state.
Spring provides a bean-friendly implementation of ThreadFactory
(CustomizableThreadFactory
) which you can inject into the SimpleAsyncTaskExecutor
, setting the daemon
property to false
.
Typically web aplications can react to container shutdown via a ServletContextListener. Implement one and use it to shut down your Executor. Ideally you should couple that with a proper shutdown of the whole Spring lifecycle. I vaguely remember that Spring had something ready-made for that purpose, so it's probably a good idea to check there as well.
You can use the @PreDestroy annotation:
@PreDestroy
protected void shutDown() {
taskExecutor.shutdown();
}
精彩评论