How Tomcat Works学习笔记<十五>

来源:互联网 发布:js获取div的style 编辑:程序博客网 时间:2024/04/27 17:50
 

Shutdown钩子

         在很多环境下,当用户停止应用以后,程序需要做一些清理。但问题是用户往往忘记按照要求退出,比如在Tomcat部署的时候,你通过实例化Server变量,调用其的start方法来启动servlet和其他的组件,在正常情况下你需要传入一个stutdown命令来停止Server及其它的组件,但是有时你可能直接关闭控制台。

         Java本身提供了很好的方案来解决在停止进程中执行相关操作,这里将会为Tomcat添加一个Shutdown钩子程序。

         在两种情况下jvm都会退出:

1、  在代码里面显示的调用System.exit()或最后的最后一个后台线程退出以后;

2、  用户强制jvm退出,如通过CTRL+C或者关闭控制台等。

在退出时,虚拟机会做两件事:

1、  如果有启动所有的Shutdown钩子,并发做相应的处理;

2、  调用所有还没有调用的finalizers。

Shutdown钩子程序刚好可以做一些清理工作,stutdown钩子都是Thread类子类的实例,创建一个shutdown钩子:

1、  写一个类继承Thread;

2、  重写其中的run方法,run方法里面的操作就是将来jvm退出的时候你需要清理的操作;

3、  在应用中实例化shutdown钩子类;

4、  通过当前线程的addShutdownHook方法注册钩子程序。

Tomcat中装备了它自己的Shutdown钩子,在负责启动Server类的org.apache.catalina.startup.Catalina中有钩子程序的实现:

protected class CatalinaShutdownHook extends Thread {

        public void run() {

            if (server != null) {

                try {

                    ((Lifecycle) server).stop();

                } catch (LifecycleException e) {

                    System.out.println("Catalina.stop: " + e);

                    e.printStackTrace(System.out);

                    if (e.getThrowable() != null) {

                        System.out.println("----- Root Cause -----");

                        e.getThrowable().printStackTrace(System.out);

                    }

                }

            }

        }

}

         在启动Server方法时注册了钩子程序:

         Thread shutdownHook = new CatalinaShutdownHook();

    // Start the new server

    if (server instanceof Lifecycle) {

        try {

                server.initialize();

                ((Lifecycle) server).start();

                try {

                    // Register shutdown hook

                    Runtime.getRuntime().addShutdownHook(shutdownHook);

                } catch (Throwable t) {

                    // This will fail on JDK 1.2. Ignoring, as Tomcat can run

                    // fine without the shutdown hook.

                }

                // Wait for the server to be told to shut down

                server.await();

            } catch (LifecycleException e) {

                System.out.println("Catalina.start: " + e);

                e.printStackTrace(System.out);

                if (e.getThrowable() != null) {

                    System.out.println("----- Root Cause -----");

                    e.getThrowable().printStackTrace(System.out);

                }

            }

        }

 

原创粉丝点击