IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 『死磕Java并发编程系列』并发编程工具类之CountDownLatch -> 正文阅读

[Java知识库]『死磕Java并发编程系列』并发编程工具类之CountDownLatch

《死磕 Java 并发编程》系列连载中,大家可以关注一波:

👍🏻『死磕Java并发编程系列』 01 十张图告诉你多线程那些破事

『死磕Java并发编程系列』 02 面试官:说说什么是Java内存模型?

『死磕Java并发编程系列』 03 面试必问的CAS原理你会了吗?

『死磕Java并发编程系列』 04 面试官:说说Atomic原子类的实现原理?

👍🏻『死磕Java并发编程系列』 05 图解Java中那18 把锁


在日常编码中,Java 并发编程可是少不了,试试下面这些并发编程工具类。

今天先带领大家一起重温学习 CountDownLatch 这个牛叉的工具类。

认识 CountDownLatch

CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间通信的作用(非互斥)。

CountDownLatch 能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成一些任务,然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务。

CountDownLatch 的使用

CountDownLatch类使用起来非常简单。

Class 位于:java.util.concurrent.CountDownLatch

下面简单介绍它的构造方法和常用方法。

构造方法

CountDownLatch只提供了一个构造方法:

//?count?为初始计数值
public?CountDownLatch(int?count)?{
??//?……
}

常用方法

//常用方法1:调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public?void?await()?throws?InterruptedException?{
??//?……
}???

//?常用方法2:和await()类似,只不过等待超时后count值还没变为0的话就会继续执行
public?boolean?await(long?timeout,?TimeUnit?unit)?throws?InterruptedException?{?
??//?……
}

//?常用方法3:将count值减1
public?void?countDown()?{
??//?……
}??

CountDownLatch 的应用场景

我们考虑一个场景:用户购买一个商品下单成功后,我们会给用户发送各种消息提示用户『购买成功』,比如发送邮件、微信消息、短信等。所有的消息都发送成功后,我们在后台记录一条消息表示成功。

当然我们可以使用单线程去完成,逐个完成每个操作,如下图所示:

但是这样效率就会非常低。如何解决单线程效率低的问题?当然是通过多线程啦。

使用多线程也会遇到一个问题,子线程消息还没发送完,主线程可能就已经打出『所有的消息都已经发送完毕啦』,这在逻辑上肯定是不对的。我们期望所有子线程发完消息主线程才会打印消息,怎么实现呢?CountDownLatch就可以解决这一类问题。

我们使用代码实现上面的需求。

import?java.util.concurrent.*;

public?class?OrderServiceDemo?{

????public?static?void?main(String[]?args)?throws?InterruptedException?{
????????System.out.println("main?thread:?Success?to?place?an?order");

????????int?count?=?3;
????????CountDownLatch?countDownLatch?=?new?CountDownLatch(count);

????????Executor?executor?=?Executors.newFixedThreadPool(count);
????????executor.execute(new?MessageTask("email",?countDownLatch));
????????executor.execute(new?MessageTask("wechat",?countDownLatch));
????????executor.execute(new?MessageTask("sms",?countDownLatch));

????????//?主线程阻塞,等待所有子线程发完消息
????????countDownLatch.await();
????????//?所有子线程已经发完消息,计数器为0,主线程恢复
????????System.out.println("main?thread:?all?message?has?been?sent");
????}

????static?class?MessageTask?implements?Runnable?{
????????private?String?messageName;
????????private?CountDownLatch?countDownLatch;

????????public?MessageTask(String?messageName,?CountDownLatch?countDownLatch)?{
????????????this.messageName?=?messageName;
????????????this.countDownLatch?=?countDownLatch;
????????}

????????@Override
????????public?void?run()?{
????????????try?{
????????????????//?线程发送消息
????????????????System.out.println("Send?"?+?messageName);
????????????????try?{
????????????????????TimeUnit.SECONDS.sleep(1);
????????????????}?catch?(InterruptedException?e)?{
????????????????????e.printStackTrace();
????????????????}
????????????}?finally?{
????????????????//?发完消息计数器减?1
????????????????countDownLatch.countDown();
????????????}
????????}
????}
}

程序运行结果:

main thread: Success to place an order
Send email
Send wechat
Send sms
main thread: all message has been sent

从运行结果可以看到主线程是在所有的子线程发送完消息后才打印,这符合我们的预期。

CountDownLatch 的限制

CountDownLatch是一次性的,计算器的值只能在构造方法中初始化一次,之后没有任何机制再次对其设置值,当CountDownLatch使用完毕后,它不能再次被使用。

大家学会了么?后面会接着讲剩余的几种并发工具类,拭目以待吧~

我是雷小帅,爱了~

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-19 07:51:35  更:2021-09-19 07:51:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:49:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码