javaのThreadを使うときの作法

javaのThreadを使うとき、 InterruptedExceptionをcatchしてそのまま無視する実装とかよくありがちです。 そうしちゃうとスレッドでつかったリソースの後始末とかができなくてリークするので、 ちゃんと後始末しましょうねというお話です。 続きを読む
1
なぎせ ゆうき @nagise

JavaのアプリでThreadを立てる場合、どのように終わるかは考えておきたい。停止条件の基本は全てのスレッド(ただしデーモンスレッドを除く)が終了すると終了するということ。では、アプリの終了ボタンが押された時にはどうするべきか

2015-06-16 16:07:03
なぎせ ゆうき @nagise

昔のawtやswingで作られたjavaのGUIのプログラムだとアプリの終了時にSystem.exit()するものが多いが、あまり良くはない。exitはVMそのものを止めてしまう

2015-06-16 16:08:26
なぎせ ゆうき @nagise

通信などを裏で行っているThreadがある場合、それらのThreadに対して終了するということを通知する。具体的には各Threadに対してinterrupt()を呼び出す。

2015-06-16 16:09:28
なぎせ ゆうき @nagise

このとき、Thread側でwait()とかで停止していればInterruptedExceptionが起きるのでcatchして適切に終了処理(リソースの解放とか)をやってやればよい。

2015-06-16 16:10:49
なぎせ ゆうき @nagise

しかし、停止中じゃない場合は普通に動き続けるのでThread内の処理ではところどころisInterrupted()で割り込みがされたかをチェックして自発的に停止させるように配慮して作っておく必要がある。ループしている場合などではそのあたりでチェック

2015-06-16 16:11:54
なぎせ ゆうき @nagise

つまり、各Threadがinterrupt()で正しく終了するように設計した上で、アプリ終了時には生きているThread全てにinterrupt()するという方針になる

2015-06-16 16:12:58
なぎせ ゆうき @nagise

なお、リソースの後始末という点ではRuntime#addShutdownHook()というものもあるので検討する価値がある docs.oracle.com/javase/jp/8/do…

2015-06-16 16:17:04
なぎせ ゆうき @nagise

反対に使ってはいけないのがObject#finalize()で、これはオブジェクトがガーベッジコレクションによって回収される直前に呼び出されるのだが、呼び出しが確実ではないのでfinalize()に依存したコードを書いてはいけない

2015-06-16 16:18:38
なぎせ ゆうき @nagise

C++のデストラクタと同じようなものだろうと思って使うと痛い目に会う。 Javaにデストラクタなんてなかった、いいね?

2015-06-16 16:19:47
なぎせ ゆうき @nagise

そうそう、後始末で思い出したけどアプリ中で一時ファイルを作りたい場合はFile#createTempFile()を検討する。そしてFile#deleteOnExit()を設定することで終了時に自動削除されるファイルを作れる。便利 docs.oracle.com/javase/jp/8/do…

2015-06-16 16:22:46
なぎせ ゆうき @nagise

なお、ここで挙げた各種の作法というのはJavaVMで動くアプリの話であって、Dalvikでは通用しない。つまり、Androidアプリを作る場合はAndroidのフレームワークの作法に則って非同期処理をし、終了処理をしなくてはならない

2015-06-16 16:24:31
なぎせ ゆうき @nagise

Object#finalize()についてはリソースの解放漏れの救済に念のため実装しておく、といった使い方がなされることがある。 もっともJava7以降、tryでAutoCloseableなリソース宣言すれば良いので解放漏れも少なくなったが。

2015-06-16 16:26:57
なぎせ ゆうき @nagise

Javaのマルチスレッドを学ぶ書籍としてはJava並行処理プログラミング amazon.co.jp/dp/4797337206 がオススメだけど絶版。 増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編 amazon.co.jp/dp/4797331623 は今でも手に入る

2015-06-16 16:35:09
なぎせ ゆうき @nagise

internetcom.jp/developer/2005… この辺の話題って今でも残ってるんだろうか。10年ぐらい前の話だけども twitter.com/java_fgtrjhyu/…

2015-06-16 16:49:37