別のスレッドに処理を任せておいて、その処理が終わったかどうかを確認したい場合、Threadクラスのjoinメソッドを使います。
joinメソッドには引数の異なる3つの種類があるようです。
- void join()
- void join(long millis)
- void join(long millis, int nanos)
引数のないjoinメソッドは該当するスレッドが終了するのを永久に待ち続けるらしいので、間違えると無限ループ発生しそうですね。間違えないように使おう。引数のあるタイプは、待機時間の上限です。指定時間を経過してもスレッドが終了しなかった場合、joinメソッドの実行は終了します。
外部のスレッドからinterruptメソッドで割り込まれた場合はInterruptExceptionが発生するそうです。
サンプルコードを以下に。
public class JoinTest extends Thread {
public void run() {
for (int i = 3; i >= 0; i--) {
try {
sleep(1000);
} catch (InterruptException e) {}
System.out.println(i);
}
}
public static void main(String[] args) {
JoinTest t = new JoinTest();
t.start();
try {
System.out.println("スレッド t の終了を待機します。");
t.join(); // runの処理が終わるのを待つ
System.out.println("スレッド t が終了しました。");
} catch (InterruptException e) {}
}
}
スレッドの終了を待つのではなく、実行中のスレッド同士で同期処理を行いたい場合は、notify, notifyAll, waitメソッドを使用するそうです。waitで待機状態に、他スレッドでnotifyかnotifyAllがコールされると、waitメソッドが終了して処理が再開されるそうです。waitメソッド中はロックが解放されるので、同じオブジェクトを使用するスレッド同士での同期を行うために使うとか。なんかここらへんは間違いないようにするためにノウハウが要りそうな気がしますね〜。
