厳密には、readで待っている最中、またはスレッドのinterruptフラグがセットされた状態で呼ばれたときに、チャネルをclose()し、さらにスレッドのinterruptフラグをセットし直し、それからClosedByInterruptExceptionを投げる。
2014-08-05 04:07:27@frsyuki それちゃんと動いてるのかな。LinuxはOSレベルではIO中に別のスレッドからcloseされた場合の動作は保証してないけど。まあ、ソース読めばいいんだけど
2014-08-05 04:07:33@kosaki55tea FileChannel.readはFileDispatcherImpl.read0に行き着くようですが、それ自体はerrno == EINTRだったら例外を投げるだけな感じがしますね。
2014-08-05 04:11:59何やらJava側で実装してある感じかな。 “AbstractInterruptibleChannel” docs.oracle.com/javase/7/docs/…
2014-08-05 04:13:15sun.misc.SharedSecrets.getJavaLangAccess().blockedOnという謎メソッドに行き着く。
2014-08-05 04:15:07結局、サーバの終了方法はどうするかな。FileInputStream.readを中断できない(たぶんSocketInputStreamも?)以上は、動作中のサーバプロセスを安全に即座に止めるのは厳しいというかイケてない感じなので、処理が終わるまで待つのが基本かな。
2014-08-05 04:20:03しかしスレッドが1本でも忙しくしていると、サーバを長時間再起動できない可能性があるというのも困るので、忙しいスレッドは処理中のまま放置しておいて新しいプロセスを立ち上げられるようにするか、忙しいスレッドをゴミの発生覚悟でひと思いにブチ殺す仕組みがあると良い。
2014-08-05 04:22:071.shutdown handlerでshutdown的なメソッドを呼んで全スレッドの終了を静かに待つ。2.時間がかかりすぎたら、Thread.interruptを呼んで回って積極的に止めようとしてみる。3.それでも時間がかかりすぎたら、多少の遺言を残して自決する。こんな感じか。
2014-08-05 04:27:592.の代わりに、supervisor的なプロセス側で、既存JVMプロセスの終了を待たずに新プロセスを立ち上げてしまう仕組みを入れる方法もある。どちらかだな。
2014-08-05 04:30:30後者の方法+ServerEngineでsupervisor的なプロセスを作るのが一番シンプルそうだけど、真面目に検証するのは大変そうだから後回しにする案。とりあえず運用でカバーだ。
2014-08-05 05:00:28そういえば、結局InterruptedIOExceptionが何なのか良く分からないな。発生する条件が不明というか使い所が不明。ClosedByInterruptExceptionは分かったけど。
2014-08-05 05:25:20