Javaコマンドラインプログラムを正常にシャットダウンするためのさまざまなアプローチに興味があります。killシグナルを送信することはできません。
私はいくつかの異なるアプローチを考えることができます。
3つ目は、プログラム出力が画面に出力されることが多いため、理想的ではありません。最初のものはあまりにも多くの努力を要します(私は怠惰です)。ほとんどのプログラマーは2番目のオプションを使用しますか?そうでない場合、他に何が可能/エレガント/シンプルですか?
あなたはこのようなことを試すことができます:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { /*
my shutdown code here
*/ }
});
編集:
シャットダウンフックはアプリのシャットダウンを実行しません。代わりに、開発者がシャットダウン時に必要なクリーンアップを実行する方法を提供します。
javaDocから ランタイム (このメソッドを使用することを計画している場合は良い読み物):
シャットダウンフックは、単に初期化されているが開始されていないスレッドです。仮想マシンがシャットダウンシーケンスを開始すると、登録されているすべてのシャットダウンフックが不特定の順序で開始され、同時に実行されます。すべてのフックが終了すると、終了時のファイナライズが有効になっている場合は、呼び出されていないすべてのファイナライザーが実行されます。最後に、仮想マシンは停止します。 .。
必要条件を満たすRuntime.getRuntime().addShutdownHook()
を使用してみてください。このようにして、グレースフルシャットダウンを実行するために、クリーンアップを実行するためのフックを登録できます。
[〜#〜]編集[〜#〜]
http://Java.Sun.com/j2se/1.4.2/docs/api/Java/lang/Runtime.html#addShutdownHook(Java.lang.Thread) public void addShutdownHook(Thread hook)新しい仮想マシンのシャットダウンフックを登録します。 Java仮想マシンは、次の2種類のイベントに応答してシャットダウンします。
2番目のオプション(ファイルのチェック)の利点は、最初のオプション(ポートでリッスン)よりも、セキュリティの可能性があることです。
適切なユーザーのみがプログラムを閉じることができるように、ファイルが作成されるディレクトリにアクセス許可を設定できます。ポートでリッスンする場合、すべてのユーザーがそのポートに接続できます。
ソケットバージョンを使用したい場合は、実装が非常に簡単です。コードは次のとおりです。
ServerSocket server = new ServerSocket(8080);
System.out.println("Socket listening!");
server.accept();
System.out.println("Connection received!");
このコードを、プログラムで開始する別のスレッドに簡単に埋め込んでから、グローバル状態を変更してシャットダウンを開始することができます。
最初の2つのオプションは、実装が簡単です。 JMXのものを使用することもできます(私はそれについてあまり知りません)。 Tomcatは最初のアプローチを使用し、2つのプロジェクトで1と2を適用しました。
JMXコンポーネントの使用を検討してください。次に、ローカルまたはネットワーク経由でJConsoleに接続し、コンポーネントと通信できます。その後、コンポーネントはプログラムを適切にシャットダウンできます。
Java 6 u 10以降では、JVisualVMでも同じことができます。
シャットダウンフックを使用することをお勧めします。これにより、標準のOSツールを使用してプログラムを制御できます。また、外部リソース(ディスク、ポートなど)への追加アクセスも必要ありません。