How Tomcat Works學習筆記

 

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);

                }

            }

        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章