【Java多线程】如何正确使用倒计时协调器:CountDownLatch

简介: CountDownLatch可以用来实现一个或者多个(注意可以有多个)线程,等待其他线程完全一组特定的操作后,才开始继续执行的操作,这些特定的操作被称作先决条件。
+关注继续查看

前言

本篇文章的代码示例已放到 github 上,Git地址为:advance(记录每一个学习过程),大家把代码下载下来之后,全局搜索一些关键代码,即可找到该文章的源码。

大家觉得有用的话,麻烦点个star👍再走呗!

使用场景

想想一个这样的场景:我要开始吃饭,需要先满足几个先决条件:

  1. 出去买菜
  2. 开始做饭
  3. 把做好的饭端上桌

只有满足这几个条件之后,我才能真正开始吃饭。同时,这里吃饭的人可能不止我一个人,或许还有我的爸爸妈妈等。

CountDownLatch可以用来实现一个或者多个(注意可以有多个)线程,等待其他线程完全一组特定的操作后,才开始继续执行的操作,这些特定的操作被称作先决条件。

基本原理

CountDownLatch内部有一个表示未完成的先决条件的计数器。当某个线程执行CountDownLatch.await()时,如果此时的计数器不为0,那么这个线程就会被阻塞掉。

每当其他线程执行CountDownLatch.countDown()时,这个计数器就会被减为0时,其他被阻塞的线程就会被自动唤醒,执行后续的操作。

常用方法

//构造器,定义计数器的初始值

public CountDownLatch(int count):

//阻塞式等待

public void await()

//超时自动唤醒式等待

public boolean await(long timeout, TimeUnit unit)

//计数器减1,若此时计数器为0,则等待的那些线程会被唤醒

public void countDown()

//获取当前计数器的值

public long getCount()

使用示例

定义买菜的异步线程

public class MaiCaiThread implements Runnable{

   private CountDownLatch countDownLatch;

   public MaiCaiThread(CountDownLatch countDownLatch) {

       this.countDownLatch = countDownLatch;

   }

   @Override

   public void run() {

       try {

           TimeUnit.SECONDS.sleep(5);

       } catch (InterruptedException e) {

           e.printStackTrace();

       }

       System.out.println("出门买菜回来了");

       countDownLatch.countDown();

   }

}

定义做饭的异步线程

public class ZuoFanThread implements Runnable{

   private CountDownLatch countDownLatch;

   public ZuoFanThread(CountDownLatch countDownLatch) {

       this.countDownLatch = countDownLatch;

   }

   @Override

   public void run() {

       try {

           TimeUnit.SECONDS.sleep(5);

       } catch (InterruptedException e) {

           e.printStackTrace();

       }

       System.out.println("饭做好了");

       countDownLatch.countDown();

   }

}

定义主线程

public class Main {

   static CountDownLatch countDownLatch = new CountDownLatch(2);

   public static void main(String[] args) throws InterruptedException {

       Thread maicai = new Thread(new MaiCaiThread(countDownLatch));

       maicai.start();

       Thread zuoFanThread = new Thread(new ZuoFanThread(countDownLatch));

       zuoFanThread.start();

       System.out.println("我想吃饭了,但是饭还没做好");

       countDownLatch.await();

       System.out.println("程序结束,我吃上饭了");

   }

}

运行结果

image

注意事项

countDownLatch的计数器不能循环使用,只能只用一次,若计数器已经减为0,后续线程尽管调用await()方法,也不会生效。

如果要循环使用的话,需要使用CyclicBarrier。


相关文章
|
2天前
|
Java
多线程与并发编程:解释什么是死锁,并给出一个在Java中发生死锁的例子。描述一下Java中的volatile关键字的作用,以及它与synchronized的区别。
多线程与并发编程:解释什么是死锁,并给出一个在Java中发生死锁的例子。描述一下Java中的volatile关键字的作用,以及它与synchronized的区别。
7 0
|
5天前
|
Java 调度
【零基础学Java】—多线程(四十九)
【零基础学Java】—多线程(四十九)
|
5天前
|
安全 Java 调度
Java-多线程进阶
Java-多线程进阶
|
5天前
|
安全 Java 容器
Java多线程案例
Java多线程案例
|
5天前
|
Java 开发工具 计算机视觉
java swing 人脸签到系统 ----- 调用 opencv 多线程
java swing 人脸签到系统 ----- 调用 opencv 多线程
25 0
|
5天前
|
Java
java多线程简单学习
java多线程简单学习
16 1
|
15天前
|
消息中间件 Java 测试技术
Java多线程消费消息
关键词:Java,多线程,消息队列,rocketmq 多线程一个用例之一就是消息的快速消费,比如我们有一个消息队列我们希望以更快的速度消费消息,假如我们用的是rocketmq,我们从中获取消息,然后使用多线程处理。
30 0
|
26天前
|
Java
java多线程
Java多线程是指在Java程序中同时运行多个线程,每个线程都是独立运行的,有自己的执行路径、栈、寄存器等资源,并且可以同步地访问共享数据。Java多线程的主要优势在于能够充分利用多核处理器,同时提升程序的并发性和响应速度。 在Java中,有多种方式可以创建和管理多线程,包括继承Thread类、实现Runnable接口和使用Executor框架等。
18 0
|
27天前
|
缓存 安全 Java
Java面试题 - 多线程(二)
Java面试题 - 多线程(二)
13 0
|
27天前
|
缓存 安全 算法
Java面试题 - 多线程(一)
Java面试题 - 多线程
43 0
热门文章
最新文章
相关产品
云迁移中心
推荐文章
更多