2010-02-10 202 views
2

我有一个使用Spring TaskExecutor的Web应用程序。任务执行程序在Web应用程序第一次加载时启动,并且该线程运行Web应用程序的整个生命周期。自从我将此线程添加到应用程序后,Oracle Application Server将不再正常关闭。我的猜测是,OAS没有关闭,因为我没有正常关闭代码中任何地方的任务执行程序线程。在哪里最好的地方是关闭网络应用程序中的任务执行器?我在Spring 2.5.6上使用Java 5。当Web服务器关闭时,关闭Web应用程序中的TaskExecutor

这里是我使用的任务执行:

<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor"/> 

回答

0

通常,web应用程序可以通过ServletContextListener对容器关闭作出反应。实施一个并使用它来关闭您的Executor。理想情况下,你应该把它与整个Spring生命周期的正确关闭结合起来。我依稀记得Spring已经为此目的准备了一些东西,所以在这里检查也是一个好主意。

+0

谢谢。 Spring有ApplicationListener接口。任何想法如何我可以取消LinkedBlockingQueue.take()块?我试过myQueue.notifyAll()。 – 2010-02-12 14:53:58

+0

我的标准答案是“永远不要在任何地方使用阻止等待”。或者注入一个称为“毒丸”的特殊对象或中断该线程,如http://stackoverflow.com/questions/812342/how-to-interrupt-a-blockingqueue-which-is-blocking-on-take – 2010-02-12 17:07:01

2

SimpleAsyncTaskExecutor没有有意义的状态,它不需要正常关闭。另外,我不确定“线程是否运行了Web应用程序的整个生命周期” - 您指的是哪个线程?

但是,它产生的线程可能会阻止您的服务器关闭。 SimpleAsyncTaskExecutor使用ThreadFactory来创建它的线程,并且默认情况下创建的线程不是守护线程,因此当启动关闭时仍然执行的任何衍生线程都将继续,并且服务器将仅在所有这些衍生线程完成。

作为解决方案,我建议使用ThreadPoolTaskExecutor而不是SimpleAsyncTaskExecutor。它有一个布尔属性,用于控制发生关闭时发生的情况,并且如果需要,它可以强制终止线程池。

如果你仍然想使用SimpleAsyncTaskExecutor,那么你可以注入一个自定义ThreadFactory它创建deamon线程。这将允许服务器关闭,无论这些派生线程的状态如何。但是,如果这些线程可能使资源处于不稳定状态,这可能会很危险。

Spring提供了bean的友好实施ThreadFactoryCustomizableThreadFactory),你可以注入SimpleAsyncTaskExecutor,在daemon属性设置为false

+0

我给这一个镜头。我的意思是“线程运行Web应用程序的整个生命周期”是,当加载Spring上下文时,我使用任务执行器来产生一个线程,这是一个消费者。此线程是执行程序创建的唯一线程,它在Web服务器关闭之前一直运行。 – 2010-02-10 13:53:14

+0

啊,那就是问题了 - 那个线程不会等到服务器关闭,服务器会等待*关闭。 – skaffman 2010-02-10 14:49:07

0

可以使用@PreDestroy注释:

@PreDestroy 
protected void shutDown() { 
    taskExecutor.shutdown(); 
} 
相关问题