并发编程之倒计锁 CountDownLatch

简介: 上文我们知道了 `Semaphore` 信号量的用法,那么这一篇基本不用学了。因为原理基本上是一样的。但是用法不太一样。`Semaphore` 是获取到资源就执行,获取不到资源就等待。`CountDownLatch` 跟 `Semaphore` 正好相反。

作者: 西魏陶渊明
博客: https://blog.springlearn.cn/

上文我们知道了 Semaphore 信号量的用法,那么这一篇基本不用学了。因为原理基本上是一样的。
但是用法不太一样。

Semaphore 是获取到资源就执行,获取不到资源就等待。
CountDownLatch 跟 Semaphore 正好相反。

CountDownLatch#await() 可以理解为获取不到资源,就等待。这么说不太好理解,直接看源码吧。

private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;

        Sync(int count) {
            setState(count);
        }

        int getCount() {
            return getState();
        }

        protected int tryAcquireShared(int acquires) {
            // 获取资源,await就是调用这个方法。当tryReleaseShared没有进行扣减之前。
            // 这里一直都是-1。而-1就是获取不到资源进行等待
            return (getState() == 0) ? 1 : -1;
        }

        protected boolean tryReleaseShared(int releases) {
            // countDown就调用这个方法,进行扣减1
            for (;;) {
                int c = getState();
                if (c == 0)
                    return false;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }
    }

常用用法

注意:
==CountDownLatch不可重复使用,当计数器减少到0之后,就废了,无法继续使用了。==

CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。

CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

CountDownLatch 存在的意义

让主线程阻塞,等待线程结束后在运行

直译过来就是倒计数(CountDown)门闩(Latch)。倒计数不用说,门闩的意思顾名思义就是阻止前进。在这里就是指 CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程。

实现

CountDownLatch内部维护一个最大线程数,当每个线程执行结束,就调用
latch.countDown(); 将数量减 1 ,当数量为0的时候,就放弃阻塞主线程,也就是放弃 countDownLatch.await() 阻塞的线程

代码解释

 public void test()throws Exception{
        int pagecount=3;
        ExecutorService executors = Executors.newFixedThreadPool(pagecount);
        CountDownLatch countDownLatch = new CountDownLatch(pagecount);
        for (int i = 0; i < pagecount; i++) {
            // 启动线程抓取
            executors
                    .execute(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println(Thread.currentThread().getName());
                            countDownLatch.countDown();
                        }
                    });
        }
        countDownLatch.await();//主线程阻塞在这里,等到线程结束,
        //然后关闭线程池
        executors.shutdown();

    }


最大缺点

通过前面源码我们发现, CountDownLatch 只有减没有加,所以导致了一个最大的缺点就是
只能使用一次,当扣减为0的时候,那么就不能在继续使用了。所以就要引入 CyclicBarrier了。

相关文章
|
移动开发 小程序 API
【产品上新】openURL接口开放,实现在小程序与H5之间“反复横跳”
【产品上新】openURL接口开放,实现在小程序与H5之间“反复横跳”
885 0
|
NoSQL Java 程序员
极速体验编译openjdk8(docker环境)
在docker环境下,用最少的步骤把openjdk8源码编译构建成jdk
1451 0
极速体验编译openjdk8(docker环境)
|
6月前
|
JavaScript 前端开发 UED
前端组件库——Arco Design Vue知识点大全(二)
教程来源 https://bncne.cn/sheyinggoutu.html Arco Design Vue提供丰富UI组件(按钮、栅格、表单、表格、反馈)及强大主题定制能力:支持Less编译时覆盖(如`arcoblue-6`主色生成10阶色板)与CSS变量运行时动态换肤,兼顾开发效率与用户体验。
|
PyTorch API 算法框架/工具
DeepSeek 部署方式与技术实践
DeepSeek的部署灵活性使其在多个领域大放异彩,但需根据场景权衡性能、成本与安全性。随着工具生态的完善与行业方案的沉淀,2025年将成为AI大模型落地关键年。开发者应持续关注MoE、COT等技术创新,结合自身需求选择最优部署策略。
1165 1
|
JavaScript 编译器 开发工具
【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
990 2
【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
|
SQL 安全 Java
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。
916 2
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
|
存储 数据采集 数据挖掘
CSV vs 数据库:数据存储的最佳选择是什么
本文介绍了爬虫数据存储中CSV和数据库的优缺点,分析了两者在不同场景下的适用性。CSV简单易用、资源消耗低,适合小量数据;数据库则在处理大量数据和复杂查询时表现出色,支持并发操作。通过Python代码示例,展示了如何使用多线程和爬虫代理IP技术将百度搜索数据存储到MySQL数据库中,适用于大型项目和复杂数据分析需求。
1061 2
|
搜索推荐 数据安全/隐私保护
智能玻璃:自适应环境变化的建筑材料
【10月更文挑战第17天】智能玻璃是一种能够根据外界环境条件自动调节透明度、颜色或隔热性能的高科技建筑材料。本文介绍了智能玻璃的工作原理(如电致变色、热致变色、光致变色)、分类、应用领域(建筑、汽车、航空)以及其在节能环保、隐私保护、光线控制等方面的卓越表现。未来,智能玻璃将更加智能化,助力建筑行业向绿色化、可持续方向发展。
1014 1
|
Ubuntu Linux
编译内核遇到pahole不可用
编译内核遇到pahole不可用