CountDownLatch 计数器
这里我暂时只讲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 计数器的更多相关文章
- java 5线程中 Semaphore信号灯,CyclicBarrier类,CountDownLatch计数器以及Exchanger类使用
先来讲解一下Semaphore信号灯的作用: 可以维护当前访问自身的线程个数,并提供了同步机制, 使用semaphore可以控制同时访问资源的线程个数 例如,实现一个文件允许的并发访问数. 请看下面 ...
- CycliBarriar和CountdownLatch(计数器)
CyclicBarrier可以重复使用,而CountdownLatch不能重复使用. countDownLatch这个类使一个线程等待其他线程各自执行完毕再执行. 是通过一个计数器来实现的,计数器的初 ...
- 并发工具类:CountDownLatch、CyclicBarrier、Semaphore
在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...
- JUC系列回顾之-CountDownLatch底层原理和示例
CountDownLatch 是一个同步工具类,允许一个线程或者多个线程等待其他线程完成操作,再执行. CountDownLatch(int count) 构造一个用给定计数初始化的 CountDow ...
- CountDownLatch——闭锁的实现之一
CountDownLatch实际上是一种闭锁实现.闭锁:是一种同步工具类,可以延迟线程的进度知道其到达终止状态--<Java并发编程实战>.这个怎么解释呢?简单来说,就是有1个线程需要等待 ...
- java并发之同步辅助类(Semphore、CountDownLatch、CyclicBarrier、Phaser)
线程同步辅助类,主要学习两点: 1.上述几种同步辅助类的作用以及常用的方法 2.适用场景,如果有适当的场景可以用到,那无疑是最好的 semaphore(seməˌfôr) 含义 信号量就是可以声明多把 ...
- Java中使用CountDownLatch进行多线程同步
CountDownLatch介绍 在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法: 1.synchronized关键字进行同步. 2.Lock锁接口及其实现类ReentrantL ...
- ccse(CountDownLatch,CycliBarrier,Semaplore,Exchanger)
关于等待状态的线程调用interrupt方法报异常:InterruptedException 当线程被阻塞,比如wait,join,sleep等,在调用interrupt方法,没有占用cpu运行的线程 ...
- Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Phaser)
我在<JDK1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...
随机推荐
- Liunx下使用wine容器实现跨平台使用软件
首先在Liunx中使用QQ,网易云音乐,等这些软件是很痛苦的,某些软件可能会有Liunx版本,但是像腾讯QQ早年前也提供过Linux版本,后来就下架了!!! 这里我以ubuntu18.04版本为列,讲 ...
- Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
745. 前缀和后缀搜索 给定多个 words,words[i] 的权重为 i . 设计一个类 WordFilter 实现函数WordFilter.f(String prefix, String su ...
- Java实现 LeetCode 495 提莫攻击
495. 提莫攻击 在<英雄联盟>的世界中,有一个叫 "提莫" 的英雄,他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态.现在,给出提莫对艾希的攻击时间序列和 ...
- Java实现 LeetCode 295 数据流的中位数
295. 数据流的中位数 中位数是有序列表中间的数.如果列表长度是偶数,中位数则是中间两个数的平均值. 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2. ...
- java实现测量到的工程数据
[12,127,85,66,27,34,15,344,156,344,29,47,-] 这是某设备测量到的工程数据. 因工程要求,需要找出最大的 5 个值. 一般的想法是对它排序,输出前 5 个.但当 ...
- awardRotate转盘插件文字模糊问题和图片加载问题
前言 最近在做一个转盘抽奖页面,使用了awardRotate.js发现字体和图片都有模糊,绘制的时候图片绘制不全,搜索一下之后发现针对awardRotate的解决方法比较少,针对canvas的比较多, ...
- 3.keras-简单实现Mnist数据集分类
keras-简单实现Mnist数据集分类 1.载入数据以及预处理 import numpy as np from keras.datasets import mnist from keras.util ...
- linux 删除文件后 df 查看磁盘空间并没有释放
1.错误现象 Linux 磁盘空间总是报警,查到到大文件,删除之后,df看到磁盘空间并没有释放. 用du -sh ./* | sort -nr (查看当前目录下文件的大小)通过查找了下发现文件被mys ...
- Mysql(Mariadb)数据库主从
Mysql主从复制的实现原理图大致如下: MySQL之间数据复制的基础是以二进制日志文件(binary log file)来实现的,一台MySQL数据库一旦启用二进制日志后,其作为master,它数据 ...
- 制作zipkin docker镜像
这里使用的zipkin知识基于内存的版本,没有接入外部存储 https://zipkin.io/ https://github.com/openzipkin/zipkin https://github ...