什么是CountDownLatch?

像我们程序员呢,经常会去参加需求评审,一般来说,都是开发、测试、产品经理都到齐了才能开始的,会议的负责人是产品经理。这里就有「等」的问题,等人齐了,就开始开会,人没有齐,会议不会开。

在程序的世界里,这种「人齐了才能干活」的场景同样也是随处可见的。比如说,一个电商系统的商品聚合详情页,需要同时去调用商品基础信息服务、库存服务和优惠券服务。为了提高响应速度,可以开启3个并发线程去分别拉取数据。但最后拼装数据返回给前端时,主线程必须等这3个子任务全部完成,任何一个数据没拿到,页面都无法完整渲染。

那么,主程序怎么知道这3个线程到底有没有到齐呢?

这时,我们就需要一位会议主持人(主线程)和签到员(同步工具CountDownLatch)。

注意,签到员才是CountDownLatch。主线程不是,CountDownLatch是用来协调线程的,在这里就是要协调主线程和子线程(协同的线程)。

为了方便大家理解和做好映射,我列一个表格,把上面需求评审会的场景跟CountDownLatch映射起来。

需求会议中的场景 Java中的代码逻辑
签到员拿出一张纸,上面写着应到3人 CountDownLatch latch = new CountDownLatch(3);
开发/测试/产品赶到会议室,向签到员报到 每个子线程完成任务后,调用latch.countDown()(计数器 -1)
主持人问签到员:人齐了吗? 签到员说:还没,你先坐着等。 主线程调用latch.await(),且被阻塞挂起
当最后一个人报到,签到员看表:还差0人,人全齐了! 计数器扣减到0
签到员叫醒主持人:可以开会了 CountDownLatch唤醒被阻塞的主线程,await()方法返回,主线程继续往下执行

好,下面我们将上面的场景,用java 17来实现。

用代码模拟

对应到代码里:主持人就是主线程,签到员就是一个CountDownLatch,开发、测试、产品经理是三个参会线程。完整代码如下:

java 复制代码
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;

public class MeetingDemo {

    public static void main(String[] args) throws Exception {
        // 签到表:应到3人,开发、测试、产品经理各一个
        CountDownLatch latch = new CountDownLatch(3);
        String[] roles = {"开发", "测试", "产品经理"};

        // 三个参会人各起一个线程,从工位走到会议室
        for (String role : roles) {
            new Thread(() -> {
                try {
                    // 走路耗时不一样,300到800毫秒不等
                    Thread.sleep(ThreadLocalRandom.current().nextInt(300, 800));
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println(role + "到了会议室");
                // 人到就向签到员报到,签到表上的名字划掉一个
                latch.countDown();
            }).start();
        }

        // 主持人(主线程)在签到员这里等,人没齐就停着
        latch.await();
        System.out.println("人到齐了,会议开始");
    }
}

运行结果如下:

text 复制代码
产品经理到了会议室
开发到了会议室
测试到了会议室
人到齐了,会议开始

三个参会人各是一个线程,走路的耗时不一样,所以每遍输出里,到达的顺序都不一样。每个人到会议室后做的事都是一样的:向签到员报到,countDown()把签到表上的名字划掉一个。主持人(主线程)到了就await(),在签到员这里等,名字没划完就一直停着。

三个名字全部划掉,计数从3减到0,await()返回,对应的就是表格里的最后一行:签到员叫醒主持人,会议开始。

业务代码里使用CountDownLatch的场景

我这边在生产环境里,是经常使用CountDownLatch的,下面我列其中一个场景,批量翻译。

由于我这边一直是从事连锁店行业的,因此相关的业务场景,也是连锁店相关的。

我们当时的门店是开到全世界的,日本,美国,澳门,香港等,都在开店,因此相关的语言是做翻译的。

当运营点一下一键翻译,一批文案要调外部翻译服务,翻成多个语种,单次调用几百毫秒。因此就做并发翻译,主线程要等这批全部翻完,才把结果组装好返回到页面。

凡是主线程需要等多个子线程干完后,才能开始的,你就可以使用CountDownLatch这个同步工具。

这篇内容的主要目的,就是让你了解什么是CountDownLatch,至于实现原理的,后续的内容会写。

感谢您的阅读,希望这篇文章可以帮助到你。

相关推荐
Promising_GEO几秒前
GEE实战02期:从卫星波段开始:利用 Sentinel-2 自己计算 NDVI
java·sentinel·遥感·空间分析
专注仿真5 分钟前
ThinkPHP6 API接口开发实例:从零搭建RESTful风格接口
后端·php·restful
大文说跨境6 分钟前
亚马逊多账号管理浏览器怎么选?云登/紫鸟/AdsPower 对比
java·前端·自动化
程序员如山石16 分钟前
AI主流开发环境搭建过程
人工智能·程序员
开心猴爷18 分钟前
应对iOS审核4.3:可以使用 IpaGuard 来给属性名混淆的技术细节与平衡之道
后端·ios
1m5555555521 分钟前
RAG 工程实战(五):正确知识已经进入 Prompt,为什么大模型还是会答错?
后端·面试
CoderYanger21 分钟前
Java EE 进阶:4.Spring Web MVC 入门(第一弹)
java·开发语言·前端·spring·面试·java-ee·mvc
易小尊21 分钟前
我的模型在 65% 以上时准得可怕,在 50% 时像在掷硬币
后端
用户27886072856722 分钟前
fallback 会盖掉平台提示词:system、空数组和 systemAppend 的差别
前端·后端
iOS开发上架哦23 分钟前
iOS应用耗电测试:使用Energy Log、Keymob和Instruments进行性能监控与能源消耗分析
后端·ios