前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Java多线程】如何正确使用倒计时协调器:CountDownLatch

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

原创
作者头像
呆小鱼LQ
发布2023-09-20 01:29:33
1970
发布2023-09-20 01:29:33
举报
文章被收录于专栏:Redis学习专栏Redis学习专栏

前言

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

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

使用场景

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

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

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

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

基本原理

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

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

常用方法

代码语言:txt
复制
//构造器,定义计数器的初始值
public CountDownLatch(int count):

//阻塞式等待
public void await()

//超时自动唤醒式等待
public boolean await(long timeout, TimeUnit unit)

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

//获取当前计数器的值
public long getCount()

使用示例

定义买菜的异步线程

代码语言:txt
复制
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();
    }
}

定义做饭的异步线程

代码语言:txt
复制
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();
    }
}

定义主线程

代码语言:txt
复制
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("程序结束,我吃上饭了");
    }
}

注意事项

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

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 使用场景
  • 基本原理
  • 常用方法
  • 使用示例
  • 注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档