CountDownLatch
是JUC
包中的一个同步工具类,允许一个或多个线程等待,直到其他线程执行完毕之后再执行。
CountDownLatch
通常有两种使用场景:
countDown()
方法。await()
方法,主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务,count 值为 0,停止阻塞,主线程继续执行。在这个场景中,CountDownLatch
可类似于发令者的角色
public class Test {
public static void main(String[] args) throws InterruptedException{
CountDownLatch count = new CountDownLatch(1);
for (int i = 0; i < 8; i++) {
new Thread(() -> {
try {
// 线程阻塞,等待所有线程就绪
count.await();
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
count.countDown(); // 计数器减1,多个线程开始同时执行
System.out.println("主线程打印");
}
}
运行结果
主线程打印
Thread-3
Thread-6
Thread-4
Thread-5
Thread-1
Thread-0
Thread-7
Thread-2
通过count.await()
使当前线程等待,直到计数器为0,或者线程被中断。由于count.countDown()
在循环外部,每个线程启动的时候都会将自己阻塞,但此时的阻塞并没有阻塞主线程,所以主线程打印先一步执行,在循环内8个线程就绪之后,通过计数器减1,让他们同步执行打印,达到并行执行的目的。
public class Test {
public static void main(String[] args) throws InterruptedException {
CountDownLatch count = new CountDownLatch(8);
for (int i = 0; i < 8; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName());
count.countDown();
}).start();
}
count.await();
System.out.println("主线程打印");
}
}
运行结果
Thread-0
Thread-2
Thread-1
Thread-3
Thread-4
Thread-5
Thread-6
Thread-7
主线程打印
count.await()
在循环外部,阻塞主线程等待其他8个线程执行count.countDown()
,当计数器为0时,才执行主线程打印
CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同: