这里我暂时只讲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 计数器的更多相关文章

  1. java 5线程中 Semaphore信号灯,CyclicBarrier类,CountDownLatch计数器以及Exchanger类使用

    先来讲解一下Semaphore信号灯的作用:  可以维护当前访问自身的线程个数,并提供了同步机制, 使用semaphore可以控制同时访问资源的线程个数 例如,实现一个文件允许的并发访问数. 请看下面 ...

  2. CycliBarriar和CountdownLatch(计数器)

    CyclicBarrier可以重复使用,而CountdownLatch不能重复使用. countDownLatch这个类使一个线程等待其他线程各自执行完毕再执行. 是通过一个计数器来实现的,计数器的初 ...

  3. 并发工具类:CountDownLatch、CyclicBarrier、Semaphore

    在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...

  4. JUC系列回顾之-CountDownLatch底层原理和示例

    CountDownLatch 是一个同步工具类,允许一个线程或者多个线程等待其他线程完成操作,再执行. CountDownLatch(int count) 构造一个用给定计数初始化的 CountDow ...

  5. CountDownLatch——闭锁的实现之一

    CountDownLatch实际上是一种闭锁实现.闭锁:是一种同步工具类,可以延迟线程的进度知道其到达终止状态--<Java并发编程实战>.这个怎么解释呢?简单来说,就是有1个线程需要等待 ...

  6. java并发之同步辅助类(Semphore、CountDownLatch、CyclicBarrier、Phaser)

    线程同步辅助类,主要学习两点: 1.上述几种同步辅助类的作用以及常用的方法 2.适用场景,如果有适当的场景可以用到,那无疑是最好的 semaphore(seməˌfôr) 含义 信号量就是可以声明多把 ...

  7. Java中使用CountDownLatch进行多线程同步

    CountDownLatch介绍 在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法: 1.synchronized关键字进行同步. 2.Lock锁接口及其实现类ReentrantL ...

  8. ccse(CountDownLatch,CycliBarrier,Semaplore,Exchanger)

    关于等待状态的线程调用interrupt方法报异常:InterruptedException 当线程被阻塞,比如wait,join,sleep等,在调用interrupt方法,没有占用cpu运行的线程 ...

  9. Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Phaser)

    我在<JDK1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...

随机推荐

  1. jchdl - RTL Data Types

    https://mp.weixin.qq.com/s/hWYW1Bn---WhpwVu2e98qA   一. Bit ​​ 类结构如下: ​​   主要属性: value: bit的值,只支持0,1, ...

  2. 从0开始探究vue-公共变量的管理

    背景 在Vue项目中,我们总会遇到一些公共数据的处理,如方法拦截,全局变量等,本文旨在解决这些问题 解决方案 事件总线 所谓事件总线,就是在当前的Vue实例之外,再创建一个Vue实例来专门进行变量传递 ...

  3. ASP.NET使用HttpHandler进行页面静态化(自动生成页面)

    这次的Demo是,一个根页面,点击链接创建子页面,子页面都是一个Template页面进行替换的 一个根页面 <%@ Page Language="C#" AutoEventW ...

  4. Java实现 LeetCode 583 两个字符串的删除操作(求最长公共子序列问题)

    583. 两个字符串的删除操作 给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符. 示例: 输入: " ...

  5. Java实现 蓝桥杯VIP 基础练习 芯片测试

    问题描述 有n(2≤n≤20)块芯片,有好有坏,已知好芯片比坏芯片多. 每个芯片都能用来测试其他芯片.用好芯片测试其他芯片时,能正确给出被测试芯片是好还是坏.而用坏芯片测试其他芯片时,会随机给出好或是 ...

  6. Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素 - 允许重复

    381. O(1) 时间插入.删除和获取随机元素 - 允许重复 设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构. 注意: 允许出现重复元素. insert(val):向集合中插 ...

  7. Java实现 计蒜客 拯救行动

    拯救行动 公主被恶人抓走,被关押在牢房的某个地方.牢房用 N \times M (N, M \le 200)N×M(N,M≤200) 的矩阵来表示.矩阵中的每项可以代表道路(@).墙壁(#).和守卫( ...

  8. Java实现 LeetCode 42 接雨水

    42. 接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这 ...

  9. java实现转方阵

    /* 对一个方阵转置,就是把原来的行号变列号,原来的列号变行号 例如,如下的方阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 转置后变为: 1 5 9 13 2 6 ...

  10. MMDVM中继板测试软件MMDVMCal

    运行方法: 只支持windows 64位系统 32位下载:https://share.weiyun.com/52uHAO5 64位下载:https://share.weiyun.com/5IgdqvL ...