简介
在现实世界中,我们常常需要等待其它任务完成,才能继续执行下一步。Java实现等待子线程完成再继续执行的方式很多。我们来一一查看一下。
Thread的join方法
该方法是Thread提供的方法,调用join()时,会阻塞主线程,等该Thread完成才会继续执行,代码如下:
private static void threadJoin() {
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < NUM; i++) {
Thread t = new Thread(new PkslowTask("Task " + i));
t.start();
threads.add(t);
}
threads.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
System.out.println("threadJoin Finished All Tasks...");
}
结果:
Task 6 is running
Task 9 is running
Task 3 is running
Task 4 is running
Task 7 is running
Task 0 is running
Task 2 is running
Task 1 is running
Task 5 is running
Task 8 is running
Task 1 is completed
Task 8 is completed
Task 6 is completed
Task 4 is completed
Task 3 is completed
Task 0 is completed
Task 7 is completed
Task 9 is completed
Task 2 is completed
Task 5 is completed
threadJoin Finished All Tasks...
CountDownLatch
CountDownLatch是一个很好用的并发工具,初始化时要指定线程数,如10。在子线程调用countDown()时计数减1。直到为0时,await()方法才不会阻塞。代码如下:
private static void countDownLatch() {
CountDownLatch latch = new CountDownLatch(NUM);
for (int i = 0; i < NUM; i++) {
Thread t = new Thread(() -> {
System.out.println("countDownLatch running...");
try {
Thread.sleep(1000);
System.out.println("countDownLatch Finished...");
latch.countDown();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t.start();
}
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("countDownLatch Finished