以下のコードは、ラッパークラスを使用してExecutor
、送信されたジョブの数をカウントし、それを完了したジョブの数と比較して、目的を達成する方法を示しています。タスクexecute
はラッパークラスのメソッドを呼び出す必要があり、基になるものExecutor
を直接呼び出さないようにする必要があることに注意してください。必要に応じて、以下のラッパーを拡張して、ifの「submit」メソッドをラップするのは簡単ExecutorService
です。
public class ExampleExecutor {
private final Executor executor;
private long submitCount = 0;
private long doneCount = 0;
public ExampleExecutor(Executor executor) {
this.executor = executor;
}
public synchronized void execute(Collection<Runnable> commands) {
for (Runnable command : commands) {
execute(command);
}
}
public synchronized void execute(final Runnable command) {
submitCount ++;
executor.execute(new Runnable() {
public void run() {
try {
command.run();
} finally {
synchronized (ExampleExecutor.this) {
doneCount++;
if (doneCount == submitCount) {
ExampleExecutor.this.notifyAll();
}
}
}
}
});
}
public synchronized void awaitCompletion() throws InterruptedException {
while (doneCount != submitCount) {
this.wait();
}
}
}
編集:上記のコードをどのように使用できるかを示すために、以下にテストケースを追加しました
public class Test {
static class Task implements Runnable {
private final String id;
private final long repetitions;
private final long respawnSize;
private final ExampleExecutor executor;
public Task(String id, long repetitions, long respawnSize, ExampleExecutor executor) {
this.id = id;
this.repetitions = repetitions;
this.respawnSize = respawnSize;
this.executor = executor;
}
public void run() {
for (int i = 0; i < respawnSize; i ++) {
// Spawning new sub tasks
executor.execute(new Task(id + "-" + i, repetitions/2, 0, null));
}
double sum = 0;
for (int i = 0; i < repetitions; i++) {
sum += Math.sin(i);
}
System.err.println(id + " completed at " + System.currentTimeMillis() + " with sum=" + sum);
}
}
public static void main(String argv[]) throws InterruptedException {
ExampleExecutor executor = new ExampleExecutor(Executors.newFixedThreadPool(2));
executor.execute(new Task("0", 2000000, 100, executor));
System.err.println("main thread awaits completion");
executor.awaitCompletion();
System.err.println("main thread recieved completion event");
}
}