ファイナライズの方法について質問です。多くの継承を持つ多くのクラスがある場合、アプリケーションを閉じるときにすべての finalize メソッドを呼び出すにはどうすればよいですか?
4 に答える
System.runFinalizersOnExit(true)
、ただし、非推奨であることに注意してください。この種のものに依存している場合、基本的にすでに何か間違ったことをしています。
finalize()
メソッドはアプリケーションの終了時に実行されません。
推奨されるアプローチは、シャットダウン フックを使用することです。
例えば
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
// shutdown logic
}
});
シャットダウン フックは、次の場合に実行されます。
- プログラムは正常に終了します。例: System.exit
- ^C の入力、ログオフ、またはシステムのシャットダウンなどのユーザー割り込み
Java は、 と呼ばれるメソッドも提供していrunFinalizersOnExit()
ます@deprecated
。次の理由により廃止されました。
他のスレッドがそれらのオブジェクトを同時に操作している間にファイナライザーがライブ オブジェクトで呼び出され、異常な動作やデッドロックが発生する可能性があります。
本質的に、runFinalizersOnExit()
安全ではありません。上で説明したように、シャットダウン フックを使用します。
物事をクリーンアップする、ログ ファイルを閉じる、アラートを送信する、または Java 仮想マシンがシャットダウンしているときに他のアクションを実行する必要がある場合、特に誰かが CTRL+C を押して VM をシャットダウンするか、強制終了信号を送信した場合Unix/Linux では、 ShutdownHookを確認する必要があります。
シャットダウン フックは、単に初期化されているが開始されていないスレッドです。仮想マシンがシャットダウン シーケンスを開始すると、登録されているすべてのシャットダウン フックが不特定の順序で開始され、同時に実行されます。finalization-on-exit が有効になっている場合、すべてのフックが終了すると、呼び出されていないすべてのファイナライザーが実行されます。最後に、仮想マシンが停止します。exit メソッドの呼び出しによってシャットダウンが開始された場合、非デーモン スレッドと同様に、デーモン スレッドはシャットダウン シーケンス中も実行し続けることに注意してください。