关闭ExecutorService

时间:2009-09-16 07:55:29

标签: java multithreading exception servlets exception-handling

在Tomcat中,我编写了一个ServletContextListener,它将在启动时启动ExecutorService,并在卸载时终止它。

我正在关注ExecutorService

的javadoc中的示例
public void contextDestroyed( ServletContextEvent sce )
{
    executor.shutdown();
    try
    {
        executor.awaitTermination( 50, TimeUnit.SECONDS );
    }
    catch( InterruptedException ie )
    {
        Thread.currentThread().interrupt();
    }
}

我的问题是我应该在contextDestroyed()方法中传播InterruptedException吗?

3 个答案:

答案 0 :(得分:5)

我会说不。容器调用contextDestroyed方法作为上下文即将被拆除的通知,它不会征求您的许可。此外,Javadoc没有定义如果从中抛出异常会发生什么,因此结果可能是不可预测的和/或不可移植的。

我要做的是在catch区域内调用executor.shutdownNow()来强行终止执行者(即“你有机会,现在停止”)。

答案 1 :(得分:1)

您的代码示例中包含的内容(重新中断当前线程)正是我所建议的。在你自己的代码之外的Tomcat中的某些东西发送了原始中断,所以让Tomcat有机会处理它。

我不知道Tomcat会对InterruptedException做什么。这是未定义的。但Tomcat发起了中断,Tomcat拥有了contextDestroyed(...)方法运行的线程。这里适用的“Java Concurrency in Practice”的一般原则是:线程的创建者负责处理线程生命 - 圆筒问题。

处理中断绝对是一个生命周期问题。

答案 2 :(得分:0)

我同意Steve的意见,重置中断标志会让控制之外的代码有机会对事件做出反应。

tempus-fugit提供了一种为您执行此操作的方法,以及如果事情花费太长时间的显式超时异常。

waitOrTimeout(shutdown(executor), timeout);

如果感兴趣的话,请查看文档的并发部分... tempusfugitlibrary.org/documentation

example演示了它的用法,包括等待完成和更积极的关闭。