Tomcat正常关闭时如何获取线程中断/通知?

时间:2016-05-27 05:18:25

标签: java spring multithreading spring-mvc tomcat

我在Tomcat服务器上运行了一个Spring Web应用程序。在这里,有一段代码,在一个Spring bean中,它等待数据库连接变得可用。我的方案是在等待数据库连接时,如果Tomcat关闭,我应该停止等待数据库连接并打破循环。

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时不会被中断。我也试图通过使用spring-bean的destroy方法实现我的场景,但令我惊讶的是,从未调用destroy方法。我的假设是Spring应用程序上下文没有完全构造 - 因为,我在Spring bean中有上面的等待循环 - 并且当调用shutdown时,不会调用相应的上下文关闭。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

Tomcat为Web应用程序定义了一个生命周期(好吧,它是一种常见的规范方面,而不仅仅是tomcat特定的,但无论如何......)

所以有一种方法可以挂钩这个过程并终止循环或其他任何东西。

在Spring中它很容易,因为如果tomcat优雅地关闭,tomcat会在实际退出进程之前尝试“取消部署”WAR。在servlet规范中,为了做到这一点,可以定义和调用特殊的Web侦听器(您可以查看javax.servlet.ServletContextListener API以获取更多信息)

现在spring实际上实现了这样一个监听器,一旦被调用,它就会关闭应用程序上下文。 一旦发生这种情况,将自动调用@PreDestroy方法。这已经是春天的东西,tomcat与此无关。

所以底线,在你的bean上指定@PreDestroy方法,它会设置一些标志或什么,它会关闭试图关闭连接的逻辑。

当然,如果只是kill -9 <tomcat's pid>,上面说的所有内容都不起作用但是在这种情况下,整个jvm会停止,所以bean无关紧要。