我不喜欢讲理论, 直接上代码看效果, 简单''粗暴''!
代码1:
public static void main(String[] args) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(3);
for (int i = 1; i < 4; i++) {
System.out.println("第" + i + "次循环开始");
countDownLatch.await();
System.out.println("第" + i + "次循环结束");
}
}
创建一个CountDownLatch对象countDownLatch, 构造参数为int类型, 这里传入3
表示:线程的倒计数个数, 可以在不同线程之间计数, 也可以在同一线程计数
调用 : countDownLatch.countDown(); 方法, 计数器就减1
上面的代码结果为:
代码2: 在同一个线程倒计数
public static void main(String[] args) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(3);
countDownLatch.countDown();
countDownLatch.countDown();
countDownLatch.countDown();
for (int i = 1; i < 4; i++) {
System.out.println("第" + i + "次循环开始");
countDownLatch.await();
System.out.println("第" + i + "次循环结束");
}
}
结果:
这里也说明, 计数器只倒计数一次, countDownLatch对象后面就没用了
代码3: 在不同线程倒计数
public static void main(String[] args) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
System.out.println(Thread.currentThread().getName() + ":执行你想要的操作");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行结束");
countDownLatch.countDown();// 线程计数器减1
}
}.start();
}
for (int i = 1; i < 4; i++) {
System.out.println("第" + i + "次循环开始");
countDownLatch.await();
System.out.println("第" + i + "次循环结束");
}
}
结果: 也在预料之中, 3个线程都执行完countDownLatch.countDown(); 后 主线程才执行第1次循环和后面的循环
应用场景:(个人观点)
与CyclicBarrier类似, 可以在每个线程的countDownLatch.countDown();方法后再添加countDownLatch.await();
那么每个线程在countDownLatch.await(); 后面的代码,也是等计数器为0后执行, 可以达到与CyclicBarrier一样的效果,
所以个人认为CountDownLatch与CyclicBarrier的区别主要是:CountDownLatch是一次性的, 而CyclicBarrier可以循环使用