13

私は Java でかなり複雑なシャットダウンをしています - やるべきクリーンアップ作業がたくさんあります。特に、シャットダウン フック スレッドからエラー処理を行う方法を理解しようとしています。私のコードには現在これが含まれています:

try {
    return shutdownPromise = doShutdown();
}
catch (Throwable exc) {
    logger.error("An exception was thrown while shutting down the application.", exc);  
    System.exit(1);
    return null;
}

私が最初にこれを書いたとき、私は基本的に、シャットダウンのエラーはそのままexit. でもexit、そんなに低レベルじゃないですよ~。シャットダウンフックを呼び出します。

ので、私は考えました -

  1. シャットダウン フックから exit を呼び出すとどうなりますか?
  2. シャットダウンフックからのエラー処理の正しい方法は何ですか?
4

1 に答える 1

23

まず、簡単な答えは、プロセスのデッドロックです。

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説明されているように、シャットダウン フックは 経由で追加されます。上記のメソッドは、最終的にのこのコード行で終了することに注意してください。sequenceShutdown.runHooks

if (hook != null) hook.run();

まず、これらのフックはアプリケーションのシャットダウン フックではないことに注意してください。これらは異なるシステム シャットダウン フックであり、そのうちの 1 つがアプリケーション シャットダウン フックの実行を保証します。startではなくrunであることに注意してください。つまり、ブロックします。これらのシャットダウン フックの 1 つは、すべてのアプリケーション シャットダウン フックを同時に開始するシステム フックであり (このコードは、自分自身またはリンクされた回答でトレースできます)、呼び出しを使用してすべてが完了するまでブロックします。これらの 1 つはアプリケーションのシャットダウン フックです。Thread.joinSystem.exitShutdown.class

次に、愚かな答えですRuntime.getRuntime().halt()。代わりに電話してください。私が「愚かな答え」と言ったのは、これはおそらく、終了する代わりにあなたがやろうとしていたわずかに低いレベルのことだからです。System.exit失敗したクリーン シャットダウンを表す場合haltは、常にすぐに成功するハード シャットダウンです。

次に、より賢明な答えは、おそらく何もないということです。次の理由により、シャットダウンフックを終了させて​​ください。シャットダウン フックはシャットダウンを所有していません。特に、他のシャットダウン フックが作業を行う必要がある場合があります。逆に言えば、このフックの役割の 1 つは、最終的にハード シャットダウンを強制することだと思います。すぐに遅延タスクとして作成し、このフックを正常に完了させることをお勧めします。

于 2013-10-23T21:11:13.737 に答える