有几种方法。
你可以先调用 ExecutorService.shutdown 然后再调用 ExecutorService.awaitTermination,它会返回:
true
如果此执行程序终止并且 false
如果在终止之前超时
所以:
有一个名为 awaitTermination
的函数。但是它需要提供一个超时时间。这并不能保证当它返回时所有任务都已经完成了。有没有一种方法可以实现这一点?
你只需要在循环中调用 awaitTermination
。
使用 awaitTermination
:
这是一个完整的示例实现:
public class WaitForAllToEnd {
public static void main(String[] args) throws InterruptedException {
final int total_threads = 4;
ExecutorService executor = Executors.newFixedThreadPool(total_threads);
for(int i = 0; i < total_threads; i++){
executor.execute(parallelWork(100 + i * 100));
}
int count = 0;
executor.shutdown();
while (!executor.awaitTermination(100, TimeUnit.MILLISECONDS)) {
System.out.println("Waiting "+ count);
count++;
}
}
private static Runnable parallelWork(long sleepMillis) {
return () -> {
try {
Thread.sleep(sleepMillis);
} catch (InterruptedException e) {
}
System.out.println("I am Thread : " + Thread.currentThread().getId());
};
}
}
使用 CountDownLatch
:
另一个选项是创建一个 CountDownLatch,其 count
等于并行任务的数量。每个线程调用 countDownLatch.countDown();
,而主线程调用 countDownLatch.await();
。
此实现的完整示例:
public class WaitForAllToEnd {
public static void main(String[] args) throws InterruptedException {
final int total_threads = 4;
CountDownLatch countDownLatch = new CountDownLatch(total_threads);
ExecutorService executor = Executors.newFixedThreadPool(total_threads);
for(int i = 0; i < total_threads; i++){
executor.execute(parallelWork(100 + i * 100, countDownLatch));
}
countDownLatch.await();
System.out.println("Exit");
executor.shutdown();
}
private static Runnable parallelWork(long sleepMillis, CountDownLatch countDownLatch) {
return () -> {
try {
Thread.sleep(sleepMillis);
} catch (InterruptedException e) {
}
System.out.println("I am Thread : " + Thread.currentThread().getId());
countDownLatch.countDown();
};
}
}
使用 CyclicBarrier
:
另一种方法是使用 循环屏障(Cyclic Barrier)。
public class WaitForAllToEnd {
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
final int total_threads = 4;
CyclicBarrier barrier = new CyclicBarrier(total_threads+ 1);
ExecutorService executor = Executors.newFixedThreadPool(total_threads);
for(int i = 0; i < total_threads; i++){
executor.execute(parallelWork(100 + i * 100, barrier));
}
barrier.await();
System.out.println("Exit");
executor.shutdown();
}
private static Runnable parallelWork(long sleepMillis, CyclicBarrier barrier) {
return () -> {
try {
Thread.sleep(sleepMillis);
} catch (InterruptedException e) {
}
System.out.println("I am Thread : " + Thread.currentThread().getId());
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
}
};
}
}
还有其他方法,但这些方法需要更改您的初始要求,即:
如何在使用 ExecutorService.execute() 提交任务时等待所有任务完成。