8

ubuntu サーバーでシャットダウン フックを動作させようとしていますが、複数のスレッドに問題があるようです。基本的な ShutdownHook を使用すると、次のコードは、 を使用してプロセスを強制終了したときに機能しkill <PID>ます。つまり、シャットダウン動作が有効になります。

public static void main(String[] args) {
    ShutdownHook shutDown = new ShutdownHook();
    shutDown.attachShutDownHook();

    while(true){}
}

ただし、追加のスレッドを使用したこの同じコードはそうではありません

public static void main(String[] args) {
    ShutdownHook shutDown = new ShutdownHook();
    shutDown.attachShutDownHook();

    (new Thread() {
        public void run() {
            while ( true ) {}
        }
    }).start();

    while(true){}
}

何か案は?

class ShutdownHook {

    ShutdownHook() {
    }

    public void attachShutDownHook() {

            Runtime.getRuntime().addShutdownHook(new Thread() {
                    @Override
                    public void run() {
                            System.out.println("Shut down hook activating");
                    }
            });
            System.out.println("Shut Down Hook Attached.");

    }
}
4

3 に答える 3

3

デーモン以外のスレッドが実行されている間は、JVM は終了しません。setDaemon(true)新しいスレッドで呼び出してみてください。

于 2012-10-31T13:22:46.010 に答える
1

私自身のプロジェクトから例を挙げると、

私のコア クラスは多数のワーカー スレッドを生成し、ワーカーは完了する必要があるトランザクションを実行します。

私が持っているコアクラスでは;

Runtime.getRuntime().addShutdownHook(new ShutdownCleanup());

これは次のようになります。

public final class ShutdownCleanup extends Thread() {
    public void run() {
        log("waiting for worker threads to finish...");
        while(WorkerThread.transactionInProgress()) {
            Thread.sleep(1000);
        }
        //close various sockets and resources
    }
}

Ctrl+Cターミナルを叩いた瞬間、logメッセージが表示されました。そのため、シャットダウン フックはすぐにアクティブになります。これは、プログラムが終了する準備ができたときに実行されるものではなく、クローズまたはキル リクエストを受信するとすぐに実行されます。

このため、スレッドがまだ生きている間にシャットダウンフックが呼び出されないことについて他の人が言ったことは誤りだと思います。いずれにせよ、すべてが停止した後にのみアクティブ化されるシャットダウン フックのポイントは何でしょうか?

-9 などのハード キルを使用している可能性があります。または を使用して通常のシャットダウンを試みましたCtrl+CSIGINT?

于 2012-10-31T13:43:16.803 に答える
0

java.lang.Runtime.addShutdownHook( Thread )新しい仮想マシンのシャットダウン フックを登録します。

Java 仮想マシンは、次の 2 種類のイベントに応答してシャットダウンします。

  • 最後の非デーモン スレッドが終了するか、exit (同等の System.exit) メソッドが呼び出されると、プログラムは正常に終了します。

  • 仮想マシンは、^C の入力などのユーザー割り込み、またはユーザー ログオフやシステム シャットダウンなどのシステム全体のイベントに応答して終了します。

コードは無期限に実行されるため、シャットダウン フックは呼び出されません。

【編集後】

あなたはどれkillを使いますか?

kill -9 はトラップできません

kill -2 は、ctrl-c (SIGINT) をエミュレートするために使用できます。

于 2012-10-31T13:21:23.603 に答える