まず、簡単な答えは、プロセスのデッドロックです。
System.exit は を呼び出し、次のコード ブロックShutdown.exit
で終了します。
synchronized (Shutdown.class) {
/* Synchronize on the class object, causing any other thread
* that attempts to initiate shutdown to stall indefinitely
*/
sequence();
halt(status);
}
コメントは完全に正確です。しかし、これを理解するには、シャットダウン フックが何をするのかを正確に確認する必要があります。
こちらの回答でApplicationShutdownHooks.add
説明されているように、シャットダウン フックは 経由で追加されます。上記のメソッドは、最終的にのこのコード行で終了することに注意してください。sequence
Shutdown.runHooks
if (hook != null) hook.run();
まず、これらのフックはアプリケーションのシャットダウン フックではないことに注意してください。これらは異なるシステム シャットダウン フックであり、そのうちの 1 つがアプリケーション シャットダウン フックの実行を保証します。startではなくrunであることに注意してください。つまり、ブロックします。これらのシャットダウン フックの 1 つは、すべてのアプリケーション シャットダウン フックを同時に開始するシステム フックであり (このコードは、自分自身またはリンクされた回答でトレースできます)、呼び出しを使用してすべてが完了するまでブロックします。これらの 1 つはアプリケーションのシャットダウン フックです。Thread.join
System.exit
Shutdown.class
次に、愚かな答えですRuntime.getRuntime().halt()
。代わりに電話してください。私が「愚かな答え」と言ったのは、これはおそらく、終了する代わりにあなたがやろうとしていたわずかに低いレベルのことだからです。System.exit
失敗したクリーン シャットダウンを表す場合halt
は、常にすぐに成功するハード シャットダウンです。
次に、より賢明な答えは、おそらく何もないということです。次の理由により、シャットダウンフックを終了させてください。シャットダウン フックはシャットダウンを所有していません。特に、他のシャットダウン フックが作業を行う必要がある場合があります。逆に言えば、このフックの役割の 1 つは、最終的にハード シャットダウンを強制することだと思います。すぐに遅延タスクとして作成し、このフックを正常に完了させることをお勧めします。