CountDownLatch::闭锁,在完成某些运算是,只有其他所有线程的运算全部完成,当前运算才继续执行。
实例化:参数:设置一个计数器的值。
final CountDownLatch latch = new CountDownLatch(5);
计数器减一:
latch.countDown();
计数器等待:
latch.await();
效果:首先初始化一个CountDownLatch对象,该对象设置计数器的值,在需要运算的地方,每次执行完一次运输,通过latch.countDown()方法来执行减一,
等到latch的初始化值减为0的时候,latch后面的代码才能执行。
例如:有5个线程,每个线程都有一些运算,需要计算5个线程全部执行完了后,花了多长时间。
假如不使用countDownLatch,直接在线程前后加上时间记录。
package com.atguigu.juc; import java.util.concurrent.CountDownLatch; /* * CountDownLatch :闭锁,在完成某些运算是,只有其他所有线程的运算全部完成,当前运算才继续执行 */ public class TestCountDownLatch { public static void main(String[] args) { LatchDemo ld = new LatchDemo(); long start = System.currentTimeMillis(); for (int i = 0; i < 5; i++) { new Thread(ld).start(); } long end = System.currentTimeMillis(); System.out.println("耗费时间为:" + (end - start)); } } class LatchDemo implements Runnable { @Override public void run() { synchronized (this) { for (int i = 0; i < 50000; i++) { if (i % 2 == 0) { System.out.println(i); } } } } }
这样计算的结果是有问题的,因为主线程本身是一个线程,即使循环里面的线程没有执行完依然会执行后面的:此时得到的结果是不准确的
long end = System.currentTimeMillis(); System.out.println("耗费时间为:" + (end - start));
要想所有线程都执行完了才计算结果,使用countDownLatch,通过计数器,闭锁。
使用CountDownLatch后的代码:
package com.atguigu.juc; import java.util.concurrent.CountDownLatch; /* * CountDownLatch :闭锁,在完成某些运算是,只有其他所有线程的运算全部完成,当前运算才继续执行 */ public class TestCountDownLatch { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(5); LatchDemo ld = new LatchDemo(latch); long start = System.currentTimeMillis(); for (int i = 0; i < 5; i++) { new Thread(ld).start(); } try { //只有当计数器的指为0的时候,这里才能执行下面的话 latch.await(); } catch (InterruptedException e) { } long end = System.currentTimeMillis(); System.out.println("耗费时间为:" + (end - start)); } } class LatchDemo implements Runnable { private CountDownLatch latch; public LatchDemo(CountDownLatch latch) { this.latch = latch; } @Override public void run() { synchronized (latch) { try { for (int i = 0; i < 50000; i++) { if (i % 2 == 0) { System.out.println(i); } } } finally { //每次执行完,该计数器减一 latch.countDown(); } } } }