首页 > 其他 > 详细

CountDownLatch 计数器

时间:2020-05-06 00:40:38      阅读:62      评论:0      收藏:0      [点我收藏+]

这里我暂时只讲CountDownLatch的作用和怎么使用,至于他是怎么实现这种功能的,涉及源码,以后我再补上。

正文

什么是CountDownLatch?

  CountDownLatch是在java1.5被引入,存在于java.util.cucurrent包下。CountDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
  他是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

为什么要使用CountDownLatch?

  在我们的业务中,可能会需要用到多线程去处理业务,而主线程必须乖乖等其他线程处理完后,再向用户返回处理结果,是成功还是失败。这时候我们该怎么办呢,CountDownLatch就能很好的实现我们的功能。

怎么使用CountDownLatch?
  CountDownLatch的使用其实很简单,我们在主线程创建一个CountDownLatch,然后将它传递给各个子线程,主线程完成自己的业务后调用await方法挂起,各子线程完成功能后,调用countDown方法将计数器减一,CountDownLatch的计数器为0后,主线程被唤醒,处理自己的业务。

举个例子

public class CountdownlachTest {
    public static void main(String[] args) {
        /** 先开个玩具厂 */
        ToyFactory factory = new ToyFactory();
        /** 玩具厂生产玩具咯,先来50个玩具 */
        int toyNum = factory.produceToy(50);
        System.err.println(toyNum + "个玩具新鲜出炉");
        CountDownLatch countDownLatch = new CountDownLatch(toyNum);
        /** 叫销售员去卖吧 */
        ToySalesperson zhangsan = new ToySalesperson("张三",12,factory,countDownLatch);
        ToySalesperson lisi = new ToySalesperson("李四",12,factory,countDownLatch);
        ToySalesperson wangwu = new ToySalesperson("王五",10,factory,countDownLatch);
        ToySalesperson zhaoliu = new ToySalesperson("赵六",16,factory,countDownLatch);
        /** 销售员干活吧 */
        zhangsan.start();
        lisi.start();
        wangwu.start();
        zhaoliu.start();
        /** 继续产玩具 */
        int produceToy = factory.produceToy(100);
        if(produceToy <= 0) {
            /** 还有玩具不给我生产,那我关厂等呗 */
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                System.err.println("玩具厂----暂停营业呢,你们来吵我干嘛");
            }
        }
        if(factory.toyNum <= 0) {
            /** 玩具卖完了,继续开工吧 */
            System.err.println("玩具厂----我又复活了,大量招工");
        }
    }
}

/**
 *     玩具工厂
 * */
class ToyFactory{
    Integer toyNum = 0;        // 玩具数量
    /** 生产玩具 */
    public int produceToy(int num) {
        if(toyNum > 0) {
            System.err.println("厂里还有玩具,必须先卖完,不能堆积");
            return 0;
        }
        this.toyNum = num;
        return this.toyNum;
    }
}
/**
 *     销售员
 * */
class ToySalesperson extends Thread{
    String name;    // 线程名
    int myToyNum;    // 我的任务量
    CountDownLatch countDownLatch;    // 剩余总量
    ToyFactory factory;
    public ToySalesperson(String name,int myToyNum,ToyFactory factory,CountDownLatch countDownLatch) {
        super(name);
        this.name = name;
        this.myToyNum = myToyNum;
        this.countDownLatch = countDownLatch;
        this.factory = factory;
    }
    @Override
    public void run() {
        /** 不断卖玩具 */
        while(true) {
            if(myToyNum <= 0) {
                System.err.println(name + "----" + "我的任务完成了,玩具卖完了,老子不用再加班了!!!");
                return;
            }
            try {
                /** 模拟到处跑卖玩具 */
                TimeUnit.SECONDS.sleep(2);
                System.err.println(name + "----" + "终于卖出一个了,真艰难啊,还剩" + myToyNum + "个");
                myToyNum--;
                countDownLatch.countDown();
                synchronized (factory.toyNum) {
                    factory.toyNum--;
                }
            } catch (InterruptedException e) {
                /** 线程被中断 */
                System.err.println(name + "----" + "老板给我穿小鞋,老子不干啦");
                return;
            }
        }
    }
}

 

CountDownLatch 计数器

原文:https://www.cnblogs.com/chongcheng/p/12833642.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!