下面的代码演示了如何使用包装类Executor
来计算提交的作业数并将其与已完成的作业数进行比较以实现您想要的结果。请注意,您的任务必须调用execute
包装类的方法,并且永远不要Executor
直接调用底层。如果需要,扩展下面的包装器以包装 an 的“提交”方法应该是微不足道的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");
}
}