java并发编程专题(八)----(JUC)实例讲解CountDownLatch

作者:rickiyang 时间:2021-12-19 16:43:22 

CountDownLatch 是一个非常实用的多线程控制工具类。” Count Down ” 在英文中意为倒计数, Latch 为门问的意思。如果翻译成为倒计数门阀, 我想大家都会觉得不知所云吧! 因此,这里简单地称之为倒计数器。在这里, 门问的含义是:把门锁起来,不让里面的线程跑出来。因此,这个工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束, 再开始执行。

CountDown Latch 的构造函数接收一个整数作为参数,即当前这个计数器的计数个数。


public CountDownLatch(int count)

CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。一个CountDownLatch初始化为给定的计数 。 调用await方法阻塞,直到当前计数为零,在调用countDown()方法之后,所有等待的线程被释放,任何后续调用await立即返回。 这是一次性的现象 - 计数不能重置。 如果需要重置计数,考虑使用CyclicBarrier ,CyclicBarrier的计数器可以被重置后使用,因此它被称为是循环的barrier。

主要方法:


// 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。
void await()
// 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。
boolean await(long timeout, TimeUnit unit)
// 递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
void countDown()
// 返回当前计数。
long getCount()

我们来看一个例子:


public class TestCountDownLatch {
 private static final int RUNNER_NUMBER = 5; // 运动员个数
 private static final Random RANDOM = new Random();
 public static void main(String[] args) {
   // 用于判断发令之前运动员是否已经完全进入准备状态,需要等待5个运动员,所以参数为5
   CountDownLatch readyLatch = new CountDownLatch(RUNNER_NUMBER);
   // 用于判断裁判是否已经发令,只需要等待一个裁判,所以参数为1
   CountDownLatch startLatch = new CountDownLatch(1);
   for (int i = 0; i < RUNNER_NUMBER; i++) {
     Thread t = new Thread(new Runner((i + 1) + "号运动员", readyLatch, startLatch));
     t.start();
   }
   try {
     readyLatch.await();
   } catch (InterruptedException e) {
     e.printStackTrace();
   }
   startLatch.countDown();
   System.out.println("裁判:所有运动员准备完毕,开始...");
 }
 static class Runner implements Runnable {
   private CountDownLatch readyLatch;
   private CountDownLatch startLatch;
   private String name;
   public Runner(String name, CountDownLatch readyLatch, CountDownLatch startLatch) {
     this.name = name;
     this.readyLatch = readyLatch;
     this.startLatch = startLatch;
   }
   public void run() {
     int readyTime = RANDOM.nextInt(1000);
     System.out.println(name + ":我需要" + readyTime + "秒时间准备.");
     try {
       Thread.sleep(readyTime);
     } catch (InterruptedException e) {
       e.printStackTrace();
     }
     System.out.println(name + ":我已经准备完毕.");
     readyLatch.countDown();
     try {
       startLatch.await(); // 等待裁判发开始命令
     } catch (InterruptedException e) {
       e.printStackTrace();
     }
     System.out.println(name + ":开跑...");
   }
 }
}

打印结果:

1号运动员:我需要547秒时间准备.
2号运动员:我需要281秒时间准备.
4号运动员:我需要563秒时间准备.
5号运动员:我需要916秒时间准备.
3号运动员:我需要461秒时间准备.
2号运动员:我已经准备完毕.
3号运动员:我已经准备完毕.
1号运动员:我已经准备完毕.
4号运动员:我已经准备完毕.
5号运动员:我已经准备完毕.
裁判:所有运动员准备完毕,开始...
3号运动员:开跑...
2号运动员:开跑...
1号运动员:开跑...
4号运动员:开跑...
5号运动员:开跑...

Process finished with exit code 0

注意:计数器必须大于等于0,只是等于0时候,计数器就是零,调用await方法时不会阻塞当前线程。

来源:https://www.cnblogs.com/rickiyang/p/11074262.html

标签:java,juc,并发编程,CountDownLatch
0
投稿

猜你喜欢

  • 如何将Mybatis连接到ClickHouse

    2023-11-06 02:35:51
  • 浅谈java对象结构 对象头 Markword

    2023-04-26 04:50:34
  • Struts2拦截器Interceptor的原理与配置实例详解

    2022-06-23 17:34:45
  • SpringBoot如何访问html和js等静态资源配置

    2023-08-17 08:07:43
  • java前后端加密解密crypto-js的实现

    2023-11-29 12:09:31
  • 浅谈Java自定义类加载器及JVM自带的类加载器之间的交互关系

    2021-09-12 23:37:24
  • C++ OpenCV单峰三角阈值法Thresh_Unimodal详解

    2022-06-09 14:36:46
  • Android基础之Fragment与Activity交互详解

    2021-12-25 16:02:11
  • java 如何给对象中的包装类设置默认值

    2022-02-09 21:04:08
  • c#装箱和拆箱知识整理

    2023-03-14 00:42:02
  • 使用注解解决ShardingJdbc不支持复杂SQL方法

    2022-08-03 02:15:12
  • Java中Validated、Valid 、Validator区别详解

    2023-11-11 13:53:31
  • C#中类的异常处理详解

    2023-02-21 17:25:01
  • Java微信公众平台开发(11) 微信三大平台的关联

    2022-10-15 06:55:56
  • Java超详细讲解排序二叉树

    2022-12-22 22:55:17
  • 当Mybatis遇上目录树超全完美解决方案

    2021-09-28 16:21:13
  • Java代码注释规范(动力节点整理)

    2022-10-26 21:01:50
  • android中Activity横竖屏切换的那些事

    2023-04-02 22:32:33
  • 详解Android中Handler的使用方法

    2023-05-03 06:35:30
  • 详解WPF如何使用必应地图控件

    2021-07-29 19:01:27
  • asp之家 软件编程 m.aspxhome.com