美文网首页
【Java多线程】如何正确使用倒计时协调器:CountDownL

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

作者: 呆小鱼LQ | 来源:发表于2023-09-19 01:50 被阅读0次

    前言

    本篇文章的代码示例已放到 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("程序结束,我吃上饭了");
        }
    }
    

    注意事项

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

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

    相关文章

      网友评论

          本文标题:【Java多线程】如何正确使用倒计时协调器:CountDownL

          本文链接:https://www.haomeiwen.com/subject/xlrnvdtx.html