プログラム内に複数のRunnableインスタンスがあり、すべてがExecutorインスタンスによってディスパッチされているとします。さらに、ある時点で、これらのランナブルのサブセットが終了するのを待ってから次に進む必要があるとします。
これを行う1つの方法は次のとおりです。
public abstract class Joinable implements Runnable {
private final Semaphore finishedLock = new Semaphore(1);
@Override
public final void run() {
try {
finishedLock.acquireUninterruptibly();
doWork();
} finally {
finishedLock.release();
}
}
public abstract void doWork();
public void join() {
finishedLock.acquireUninterruptibly();
}
}
クラスを実装すると、実行中に何を実行するかを定義するために、run()ではなくdoWork()を単純にオーバーライドできます。
参加プロセスは次のようになります。
void doStuff() {
Executor executor = Executors.newCachedThreadPool();
List<Joinable> joinables = new LinkedList<Joinable>();
// Fill joinables with implementors of Joinable...
List<Runnable> others = new LinkedList<Runnable>();
// Fill others with implementors of Runnable...
for(Joinable joinable : joinables)
executor.execute(joinable);
for(Runnable runnable : others)
executor.execute(runnable);
for(Joinable joinable : joinables)
joinable.join();
// Continue, no matter what the threads in others are up to.
}
これはこの問題を解決するための良い方法ですか(それは安全ですか?)、またはより良い方法がありますか?