Java にスレッド A があるとします。このスレッドは、いくつかのタスク A を実行し続けます。別のスレッド B は、タスク A が終了した後にのみタスク B を実行する必要があります。これを Java で実装するにはどうすればよいですか?
3 に答える
Thread.join()
別のスレッドが終了するまで、基本的に 1 つのスレッドをブロックするために使用できます。
// In thread B
threadA.join();
doStuff();
エグゼキュータ サービスなどを介してスレッド プールを使用する場合、これは正しく機能しないことに注意してください。それを行う必要がある場合 (そして、「生の」スレッドの代わりにエグゼキューターを使用することを一般的にお勧めします)、エグゼキューター タスクが完了したことをリスナーに通知する必要があります (たとえば、 を介してCountDownLatch
)。
Guavaを使用する場合は、 も参照する必要がありますListenableFuture
。これにより、物事が簡素化されます。
Java SE 7 では、 CountDownLatchを使用できます。ここに例があります。CountDownLatch を使用することで得られる利点は、必要な一定数のカウントダウンで初期化できるため、一連のスレッドを待機できることです。また、スレッドを完了する必要はありません (join() のように)。スレッドは任意の場所で countDown() を呼び出して実行を継続できます。
また、別のアプローチはCyclicBarrierです。
class Starter {
public static void main(String[] args) {
CountDownLatch signal = new CountDownLatch();
Thread a = new Worker(signal);
Thread b = new AnotherWorker(signal);
a.start();
b.start();
//doSomethingElse
}
}
class Worker extends Thread {
CountDownLatch signal;
Worker(CountDownLatch signal) {
this.signal = signal;
}
public void run(){
//doSomething
signal.await(); //wait until thread b dies
//doSomethingElse
}
}
class AnotherWorker extends Thread {
CountDownLatch signal;
AnotherWorker(CountDownLatch signal) {
this.signal = signal;
}
public void run(){
//doSomething
signal.countDown(); //notify a about finish
}
}
これを実現するには、Thread Exceutor を使用できます。エグゼキュータは値をスレッド プールに保持します。このリンクを参照してください。
http://www.journaldev.com/1069/java-thread-pool-example-using-executors-and-threadpoolexecutor
こちらもご覧ください