在开发中处理一些问题会使用多线程提升处理效率,但是又想有一个最终的结果输出来确认所有任务已经全部处理完成,此时就需要主线程等待所有子线程处理完成之后再输出结果。本次提供两种简单明了的Demo用于记录与分享。
CountDownLatch 计数器方案
public void countDownLatchDemo() {
int count = 10;
CountDownLatch latch = new CountDownLatch(count);
ExecutorService executorService = Executors.newFixedThreadPool(2);
for (int i = 0; i < count; i++) {
int finalI = i;
executorService.submit(() -> {
try {
System.out.println(finalI + "执行了, 子线程:" + Thread.currentThread().getName());
} finally {
latch.countDown();
}
});
}
try {
latch.await();
} catch (Exception e) {
e.printStackTrace();
}
executorService.shutdown();
System.out.println("线程池已关闭,主线程完成");
}
计数器方案需要处理前就清楚自己要处理的任务数,每个子线程处理完计数器都减少一次,直到计数器的值为零,主线程就不会被阻塞了,此时就可以进行最后的信息输出。
计数器方案当然也可以直接使用AtomicInteger 自减处理。
Future 线程接口回调方案
public void futureDemo() {
ExecutorService executorService = Executors.newFixedThreadPool(2);
List<Future> futureList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
int finalI = i;
Future<?> submit = executorService.submit(() -> System.out.println(finalI + "执行了, 子线程:" + Thread.currentThread().getName()));
futureList.add(submit);
}
try {
while (true) {
boolean out = false;
for (Future future : futureList) {
out = future.isDone();
if (!out) break;
}
if (out) break;
}
} catch (Exception e) {
e.printStackTrace();
}
executorService.shutdown();
System.out.println("线程池已关闭,主线程完成");
}
Future 的方案是通过循环的确认所有的Future对象是否已经全部结束,如果已经全部结束,主线程输出最终结果信息,此方案会有额外的消耗,如果增加时间间隔的话,在计时上会不是很准确。