Naoki Kurosawa
naoki_kuros****@ybb*****
2003年 5月 26日 (月) 01:32:38 JST
黒澤です。 分散サーバのShutdownHookですが、 よく考えるとどう書いていいかわかりませんね。 #よく考えると分からない、というのはよく考えてないからか? #酔っ払っているからか? というのは、 Ctrl+Cで止めたとき、メインスレッドがsynchronizedセクションにいても 強制的に止められてしまうと考えると、 (この考え方が合っているのか分からないんですが) せっかくsynchronizedセクションで囲っていても、 データが不整合状態になりえるからです。 不整合状態のデータを送信していいのかというとだめなんですが、 強制終了時に不正なデータを送信しないようにする仕組みは 普通にsynchronizedセクションを使っただけでは作れないということになります。 ググってみてもCtrl+Cで終了する際のVMの動きを詳しく解説している情報が 見つからなくてちょっと困っています。 シャットダウンフックが動作中でもデーモンスレッドは動作し続ける、 という情報はAPIリファレンスから読めるんですが、 Ctrl+Cが押されたとき、デーモンスレッドでないスレッドは どうなるんだろう? SwingアプリでShutdownHookを使って、 編集中のデータを保存しますか?なんていうダイアログを出すアプリを 作ったことがあるんですが、 それができるということは、Swingを動かしているスレッドは生きている ということになるわけで…。 #OSからのWindowメッセージを処理しているのはSwingスレッドで、 #Swingスレッド以外がすべて終了していてもアプリが終了しない #ということはSwingスレッドはデーモンスレッドではないということに #なります。 ShutdownHookからUIが呼び出せるということは、 デーモンスレッドでないスレッドも生きているということになってしまい、 じゃ、どうやってスレッドは終了するんだー、ということになります。 スレッドの終了の仕方はrunメソッドから復帰することを推奨すると、 どっかに書いてあります。 なぜかというと、Windows OSはDLLに突然の終了を通知する仕組みがないので、 さくっとスレッドやプロセスをKILLするとリソースリークが発生する 恐れがあり、行儀よく終了してくれないと困るからです。 Ctrl+Cが押されたときにJavaで行儀よく終了するには、終了させたいときに Exceptionを発生させるのがいいと思います (Exceptionならcatchやfinallyでリソース開放ができる)。 それに相当しそうなのがThreadクラスのinterruptメソッドですが、 interruptすることでExceptionが発生するのは、 throws InterruptException/InterruptedIOException宣言されている メソッドのみです。 (Thread.wait, joinやIOのread,write) 大体、Ctrl+CでExceptionが発生したら、スタックトレースが出ますね。 IOやらThreadやらのAPIにアクセスしない無限ループを作って、 Ctrl+Cが効くか試してみればいいかな? んー、謎。 とりあえず謎なまま実装しておいて、 のちのちGUIアプリにしちゃってjavawで起動してCtrl+Cなんか 受け付けないようにしちゃいますか。 分散サーバプログラムの自動アップデータとか作りたいしなー。 -- Naoki Kurosawa <naoki_kuros****@ybb*****>