Java 关闭服务

Java 关闭服务,java,multithreading,exception,servlets,exception-handling,Java,Multithreading,Exception,Servlets,Exception Handling,在Tomcat中,我编写了一个ServletContextListener,它将在启动期间启动ExecutorService,并在卸载时终止它 我遵循javadoc中的示例 我的问题是我应该在contextDestroyed()方法中传播InterruptedException吗?我会说不。容器调用contextDestroyed方法作为上下文即将被删除的通知,它没有请求您的许可。另外,Javadoc没有定义如果抛出异常会发生什么,因此结果可能不可预测和/或不可移植 我要做的是在catch块内调

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

我遵循javadoc中的示例


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

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


我要做的是在catch块内调用executor.shutdownNow(),强制终止executor(即“you have your chance,now stop”)。

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

我不知道Tomcat将如何处理InterruptedException。没有定义。但是Tomcat启动了中断,Tomcat拥有contextDestroyed(…)方法正在运行的线程。这里应用的“Java并发实践”的一般原则是:线程的创建者负责处理线程生命周期问题


处理中断肯定是一个生命周期问题。

我同意Steve的观点,重置中断标志会让您无法控制的代码有机会对事件做出反应

tempus fugit为您提供了一种方便的方法,如果时间太长,还提供了一个显式超时异常

waitOrTimeout(shutdown(executor), timeout);
如果感兴趣,请查看文档的并发部分。。。tempusfugitlibrary.org/documentation


这说明了它的用途,包括等待完成和更激进的关机。

如果它是“不可预测的”,那么如果抛出异常会发生什么最糟糕的事情?+1推荐使用shutDownNow()。吸收异常并在这里设置标志确实是正确的做法。最坏的情况是,执行回调的代码无法捕获异常,线程崩溃。但是,更重要的是,请考虑来自“awaitTermination()”的异常指示了什么。所有的异常意味着线程不能继续等待所有线程完成,因为它被另一个线程中断,这表明它应该终止。如果您没有进行阻塞调用,中断标志将在后台设置,您甚至不知道它。所以正确的做法是设置标志,即终止执行者并设置标志。@Tim我不明白你所说的“设置标志”是什么意思。你是说线程中断标志吗?shutdownNow也不能保证关机。它与关机的不同之处在于它a)中断所有正在运行的任务b)不执行任何已排队的任务。shutdown()不会中断,它允许所有正在运行的任务完成。我会从shutdownNow()开始,甚至不用为shutdown()操心。但是,如果您的Runnable不能很好地处理中断,它们可能无法正确地中断。因此,在这种情况下,记录和忽略异常是可以接受的,因为JVM最终应该关闭。您知道Tomcat将如何处理InterruptedException吗?您的执行器是否关闭?我的不是,虽然我用了同样的代码。。。(还有更多的方法)我的也不会用相同的代码关闭。我使用Tomcat7
waitOrTimeout(shutdown(executor), timeout);