Countdownlatch使用详解
Countdownlatch是什么
官方定义:
翻译过来就是:
一种同步帮助,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成为止的类。
一个CountDownLatch初始化为给定 数。该await方法将阻塞,直到count由于该countDown()方法的调用使值达到零 为止 ,此后所有等待线程都被释放,并且随后的所有awaitreturn 调用都将立即释放。这是一种一次性现象-无法重置计数。
背景
- jdk1.5被引用,跟它一起引用的还有 Cyclicbarrer,concurrentHashMap和BlockingQueue等
- 文件位置:存在于java.util.cucurrent包下。
源码
- countDownLatch类中只提供了一个构造器
//参数count为计数值
public CountDownLatch(int count) { };
该类中有三个比较重要的方法:
//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
//将count值减1
public void countDown() { };
演示
// 一个CountDouwnLatch实例是不能重复使用的,也就是说它是一次性的,锁一经被打开就不能再关闭使用了,如果想重复使用,请考虑使用CyclicBarrier。
public class CountDownLatchTest {
// 模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。
public static void main(String[] args) throws InterruptedException {
// 开始的倒数锁
final CountDownLatch begin = new CountDownLatch(1);
// 结束的倒数锁
final CountDownLatch end = new CountDownLatch(10);
// 十名选手
final ExecutorService exec = Executors.newFixedThreadPool(10);
for (int index = 0; index < 10; index++) {
final int NO = index + 1;
Runnable run = new Runnable() {
public void run() {
try {
// 如果当前计数为零,则此方法立即返回。
// 等待
begin.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("No." \+ NO + " arrived");
} catch (InterruptedException e) {
} finally {
// 每个选手到达终点时,end就减一
end.countDown();
}
}
};
exec.submit(run);
}
System.out.println("Game Start");
// begin减一,开始游戏
begin.countDown();
// 等待end变为0,即所有选手到达终点
end.await();
System.out.println("Game Over");
exec.shutdown();
}
}
CountDownLatch和CyclicBarrier区别:
- CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的
- CountDownLatch 参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier 参与的线程职责是一样的。