这里我暂时只讲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; } } } }
原文:https://www.cnblogs.com/chongcheng/p/12833642.html