Java 当Tomcat正常关闭时,如何获取线程中断/通知?
我有一个在Tomcat服务器上运行的spring web应用程序。在其中一个Springbean中有一段代码,它等待数据库连接变得可用。我的场景是,在等待数据库连接时,如果Tomcat关闭,我应该停止等待DB连接并中断循环Java 当Tomcat正常关闭时,如何获取线程中断/通知?,java,spring,multithreading,spring-mvc,tomcat,Java,Spring,Multithreading,Spring Mvc,Tomcat,我有一个在Tomcat服务器上运行的spring web应用程序。在其中一个Springbean中有一段代码,它等待数据库连接变得可用。我的场景是,在等待数据库连接时,如果Tomcat关闭,我应该停止等待DB连接并中断循环 private Connection prepareDBConnectionForBootStrapping() { Connection connection = null; while (connection == null &&
private Connection prepareDBConnectionForBootStrapping() {
Connection connection = null;
while (connection == null && !Thread.currentThread().isInterrupted()) {
try {
connection = getConnection();
break;
} catch (MetadataServerException me) {
try {
if (!Thread.currentThread().isInterrupted()) {
Thread.sleep(TimeUnit.MINUTES.toMillis(1));
} else {
break;
}
} catch (InterruptedException ie) {
logger.error("Thread {} got interrupted while wating for the database to become available.",
Thread.currentThread().getName());
break;
}
}
}
return connection;
}
上面的代码由Tomcat的一个线程执行,在调用shutdown时不会被中断。我还尝试使用Springbean的destroy方法来实现我的场景,但令我惊讶的是,destroy方法从未被调用。我的假设是,Spring应用程序上下文没有得到完全构造——因为,我在Springbean中有上面的等待循环——当调用shutdown时,相应的上下文close没有被调用
有什么建议吗?Tomcat为Web应用程序定义了一个生命周期(这是一种常见的规范方面,不仅是Tomcat特有的,而且无论如何……) 所以有一种方法可以钩住这个过程并终止循环或其他任何东西 在春天,这非常容易,因为如果tomcat优雅地关闭,tomcat会在实际退出过程之前尝试“解除”战争。在servlet规范中,为了做到这一点,可以定义并调用一个特殊的web侦听器(有关更多信息,请参见
javax.servlet.ServletContextListener
API)
现在spring实际上实现了这样一个侦听器,一旦被调用,它就会关闭应用程序上下文。
一旦发生这种情况,将自动调用@PreDestroy
方法。这已经是春天的事了,tomcat与此无关
因此,底线是,在bean上指定@PreDestroy
方法,该方法将设置一些标志或其他内容,它将关闭尝试关闭连接的逻辑
当然,如果您只是
kill-9Tomcat为Web应用程序定义了一个生命周期(好吧,这是一种常见的规范方面,不仅是Tomcat特有的,而且无论如何……),那么上面所述的一切都不会真正起作用
所以有一种方法可以钩住这个过程并终止循环或其他任何东西
在春天,这非常容易,因为如果tomcat优雅地关闭,tomcat会在实际退出过程之前尝试“解除”战争。在servlet规范中,为了做到这一点,可以定义并调用一个特殊的web侦听器(有关更多信息,请参见javax.servlet.ServletContextListener
API)
现在spring实际上实现了这样一个侦听器,一旦被调用,它就会关闭应用程序上下文。
一旦发生这种情况,将自动调用@PreDestroy
方法。这已经是春天的事了,tomcat与此无关
因此,底线是,在bean上指定@PreDestroy
方法,该方法将设置一些标志或其他内容,它将关闭尝试关闭连接的逻辑
当然,如果你只是kill-9,上面所说的一切都不会真正起作用,那么你是说Tomcat正在运行的JVM没有被关闭吗?@ScaryWombat是的,这确实是我关闭Tomcat服务时发生的事情。这是真的吗?如果Tomcat被关闭,为什么bean会请求连接?为什么不能按需立即提供连接?如果没有,为什么getConnection()
不只是在出现之前阻塞?@EJP,我们的web应用程序需要等待db连接可用-服务可以以任何顺序启动。在等待过程中,如果有人关闭了web应用程序,那么它应该正常关闭。那么你是说Tomcat正在运行的JVM没有被关闭吗?@ScaryWombat是的,这确实是我关闭Tomcat服务时发生的情况。这是真的吗?如果Tomcat被关闭,为什么bean会请求连接?为什么不能按需立即提供连接?如果没有,为什么getConnection()
不只是在出现之前阻塞?@EJP,我们的web应用程序需要等待db连接可用-服务可以以任何顺序启动。在等待过程中,如果有人关闭了web应用程序,那么它应该会正常关闭。谢谢。我们已经准备好了所有这些,正如我在问题中提到的,Spring实现功能的方式对我们不起作用。你的意思是,bean上根本没有调用标记为@PreDestroy的方法吗?是的。这可能是由于上下文本身从未被完全构建的原因——我的推测。正如我提到的,等待逻辑实际上是在SpringBean中。好吧,这是Spring的一种奇怪用法。。。为了正常运行,必须构建Spring上下文。至于你所描述的,有两个可能的原因。1.注释配置是不允许的(如果您为xml或其他东西配置spring),在这种情况下,只需在bean定义中使用“destroy method”。2.应用程序卡在等待调用中。如果是这样,则生成一个线程,该线程将处理阻塞调用,并且不会干扰spring启动生命周期逻辑。同样,为了得到一个完全运行的spring驱动的webapp,必须初始化上下文。这正是我们的用例。在建立db连接之前,我们不能允许数据库bean可用,因为有一些初始化逻辑需要db连接。顺便说一句,我们启用了注释配置,我也尝试了XML方式。谢谢。我们已经准备好了所有这些,正如我在问题中提到的,Spring实现功能的方式对我们不起作用。你的意思是,bean上根本没有调用标记为@PreDestroy的方法吗?是的。这可能是由于上下文本身从未被完全构建的原因——我的推测。正如我所提到的,等待逻辑实际上是在SpringBean中