CountdownLatch至关于一个倒计时的计数器,当计数到达0时,等待这个计数器的线程就开始执行。java
下面经过代码看一下CountdownLatch的执行效果。dom
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- public class CountdownLatchTest {
- public static void main(String[] args) {
- ExecutorService service = Executors.newCachedThreadPool();
- final CountDownLatch cdOrder = new CountDownLatch(1);//计数器的初始值为1
- final CountDownLatch cdAnswer = new CountDownLatch(3);//计数器的初始值为3
- for(int i=0;i<3;i++){//启动3个线程
- Runnable runnable = new Runnable(){
- public void run(){
- try {
- System.out.println("线程" + Thread.currentThread().getName() +
- "正准备接受命令");
- cdOrder.await();//3个线程都在等待计数器,当计数为0时,都开始往下执行
- System.out.println("线程" + Thread.currentThread().getName() +
- "已接受命令");
- Thread.sleep((long)(Math.random()*10000));
- System.out.println("线程" + Thread.currentThread().getName() +
- "回应命令处理结果");
- cdAnswer.countDown();//每一个线程结束的时候把计数器减1
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- };
- service.execute(runnable);
- }
- try {//主线程
- Thread.sleep((long)(Math.random()*10000));
- System.out.println("线程" + Thread.currentThread().getName() +
- "即将发布命令");
- cdOrder.countDown();//将计数器的计数减1
- System.out.println("线程" + Thread.currentThread().getName() +
- "已发送命令,正在等待结果");
- //主线程在等待另一个计数器(cdAnswer)为0,当为0时,开始向下执行。它(cdAnswer)的初始值为3,
- cdAnswer.await();
- System.out.println("线程" + Thread.currentThread().getName() +
- "已收到全部响应结果");
- } catch (Exception e) {
- e.printStackTrace();
- }
- service.shutdown();
- }
- }
上述CountdownLatch的代码例子中,有两个计数器ide
- final CountDownLatch cdOrder = new CountDownLatch(1);
至关于在运动会上发布信号的指挥员,指挥员一吹哨子,3个“运动员”(线程)开始执行。spa
- final CountDownLatch cdAnswer = new CountDownLatch(3);
至关于公布成绩的裁判,每一个运动员到达终点时,给裁判一个信号,“我到了(至关于将计数器减1)”,当3个“运动员”(线程)都到达时,裁判才会公布成绩,即线程
- cdAnswer.await();
下面的代码才会执行。get
总结:CountDownLatch能够实现“一我的”通知“多我的”的效果,也能够实现“多我的”通知“一我的”的效果。string