CyclicBarrier、CountDownLatch、Semaphore 的用法

CyclicBarrier、CountDownLatch、Semaphore 的用法

CountDownLatch(线程计数器 )

CountDownLatch 类位于 java.util.concurrent 包下,利用它可以实现类似计数器的功能。比如有一个任务 A,它要等待其他 4 个任务执行完毕之后才能执行,此时就可以利用 CountDownLatch来实现这种功能了。

final CountDownLatch latch = new CountDownLatch(2);
new Thread() {
    public void run() {

        System.out.println("子线程" + Thread.currentThread().getName() + "正在执行");

        Thread.sleep(3000);

        System.out.println("子线程" + Thread.currentThread().getName() + "执行完毕");

        latch.countDown();

    }

    ;
}.start();

new Thread() {
    public void run() {

        System.out.println("子线程" + Thread.currentThread().getName() + "正在执行");

        Thread.sleep(3000);

        System.out.println("子线程" + Thread.currentThread().getName() + "执行完毕");

        latch.countDown();

    }

    ;
}.start();

System.out.println("等待 2 个子线程执行完毕...");

latch.await();

System.out.println("2 个子线程已经执行完毕");

System.out.println("继续执行主线程");
CyclicBarrier(回环栅栏-等待至 barrier 状态再全部同时执行)

字面意思回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier 可以被重用。我们暂且把这个状态就叫做barrier,当调用 await()方法之后,线程就处于 barrier 了。

CyclicBarrier 中最重要的方法就是 await 方法,它有 2 个重载版本:

  1. public int await():用来挂起当前线程,直至所有线程都到达 barrier 状态再同时执行后续任务;

  2. public int await(long timeout, TimeUnit unit):让这些线程等待至一定的时间,如果还有线程没有到达 barrier 状态就直接让到达 barrier 的线程执行后续任务。

具体使用如下,另外 CyclicBarrier 是可以重用的。

public static void main (String[]args){

            int N = 4;

            CyclicBarrier barrier = new CyclicBarrier(N);

            for (int i = 0; i < N; i++)

                new Writer(barrier).start();

        }

        static class Writer extends Thread {

            private CyclicBarrier cyclicBarrier;

            public Writer(CyclicBarrier cyclicBarrier) {

                this.cyclicBarrier = cyclicBarrier;

            }

            @Override

            public void run() {

                try {

                    Thread.sleep(5000); //以睡眠来模拟线程需要预定写入数据操作

                    System.out.println("线程" + Thread.currentThread().getName() + "写入数据完

                            毕,等待其他线程写入完毕");

                            cyclicBarrier.await();

                } catch (InterruptedException e) {

                    e.printStackTrace();

                } catch (BrokenBarrierException e) {

                    e.printStackTrace();

                }

                System.out.println("所有线程写入完毕,继续处理其他任务,比如数据操作");

            }

        }
Semaphore(信号量-控制同时访问的线程个数)

Semaphore 翻译成字面意思为 信号量,Semaphore 可以控制同时访问的线程个数,通过acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

Semaphore 类中比较重要的几个方法:

  1. public void acquire(): 用来获取一个许可,若无许可能够获得,则会一直等待,直到获得许可。

  2. public void acquire(int permits):获取 permits 个许可

  3. public void release() { } :释放许可。注意,在释放许可之前,必须先获获得许可。

  4. public void release(int permits) { }:释放 permits 个许可

上面 4 个方法都会被阻塞,如果想立即得到执行结果,可以使用下面几个方法

  1. public boolean tryAcquire():尝试获取一个许可,若获取成功,则立即返回 true,若获取失败,则立即返回 false

  2. public boolean tryAcquire(long timeout, TimeUnit unit):尝试获取一个许可,若在指定的时间内获取成功,则立即返回 true,否则则立即返回 false

  3. public boolean tryAcquire(int permits):尝试获取 permits 个许可,若获取成功,则立即返回 true,若获取失败,则立即返回 false

  4. public boolean tryAcquire(int permits, long timeout, TimeUnit unit): 尝试获取 permits个许可,若在指定的时间内获取成功,则立即返回 true,否则则立即返回 false

  5. 还可以通过 availablePermits()方法得到可用的许可数目。

例子:若一个工厂有 5 台机器,但是有 8 个工人,一台机器同时只能被一个工人使用,只有使用完了,其他工人才能继续使用。那么我们就可以通过 Semaphore 来实现:

 int N = 8; //工人数

Semaphore semaphore = new Semaphore(5); //机器数目

for(int i=0;i<N;i++)

new Worker(i,semaphore).start();

}
static class Worker extends Thread {

    private int num;

    private Semaphore semaphore;

    public Worker(int num, Semaphore semaphore) {

        this.num = num;

        this.semaphore = semaphore;

    }

    @Override

    public void run() {

        try {

            semaphore.acquire();

            System.out.println("工人" + this.num + "占用一个机器在生产...");

            Thread.sleep(2000);

            System.out.println("工人" + this.num + "释放出机器");

            semaphore.release();

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }
}


„ CountDownLatch 和 CyclicBarrier 都能够实现线程之间的等待,只不过它们侧重点不同;CountDownLatch 一般用于某个线程 A 等待若干个其他线程执行完任务之后,它才执行;而 CyclicBarrier 一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;另外,CountDownLatch 是不能够重用的,而 CyclicBarrier 是可以重用的。„ Semaphore 其实和锁有点类似,它一般用于控制对某组资源的访问权限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/236845.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

建筑可视化数据大屏汇总,UI源文件(PC端大屏设计)

酷炫的大屏设计让数据更好的展现&#xff0c;方便业务人员分析数据&#xff0c;辅助领导决策。现在分享大屏Photoshop源文件&#xff0c;以下为部分截图示意。 划重点&#xff1a;文末可获得完整素材包~ 01 科技建筑平台数据可视化 02 建筑公司可视化数据汇总平台 03 深蓝…

软件开发流程分析

软件开发流程分析 相关概念1 原型设计2 产品设计3 交互设计4 代码实现详细步骤 相关概念 前端&#xff1a;自研API&#xff0c;调用第三放API 后端&#xff1a;自研API&#xff0c;第三方API 数据库&#xff1a;Mysql&#xff0c;数据采集&#xff0c;数据迁移 服务器&#xf…

软件兼容性测试:保障多样化用户体验的重要功能

随着移动设备和操作系统的快速发展&#xff0c;软件兼容性测试变得越发重要。这项测试确保软件在不同平台、设备和环境下都能够正常运行&#xff0c;提供一致而稳定的用户体验。下面是软件兼容性测试中的一些关键功能&#xff1a; 1. 跨平台兼容性测试 在不同操作系统上运行的软…

Shopify二次开发之五:元字段(Metafields)

目录 解释 操作 1、添加Custom data 2、选择特定类型的数据 3、为Page配置元子段和值 4、模板访问 解释 Shopify Metafields 是一种用于存储和管理自定义数据的功能。它们允许商户在商城中的产品、订单、客户、Page等对象上添加自定义字段&#xff0c;以满足特定业务需求…

【计算机网络】应用层电子邮件协议

一、电子邮件系统架构 电子邮件是一个典型的异步通信系统&#xff0c;发送方从UA&#xff0c;也就是邮件客户端&#xff0c;通过应用层SMTP协议&#xff0c;传输层tcp协议&#xff0c;发送给发送方的邮件服务器&#xff0c;比如使用的是163邮箱&#xff0c;163提供的SMTP服务器…

3D民俗非遗全景云展馆更高效低投入地传承传统文化

在数字化时代&#xff0c;VR全景沉浸式展示方案成为各行业打造沉浸式展示的新玩法。云览互动为企业和机构提供专业的VR全景沉浸式展示方案&#xff0c;通过虚拟体验带来前所未有的沉浸感和视觉冲击&#xff0c;为用户带来全新的体验。 非遗虚拟VR云展平台是一种全新的物质文化遗…

【MATLAB】基于CEEMD分解的信号去噪算法(基础版)

代码的使用说明 【MATLAB】基于CEEMD分解的信号去噪算法&#xff08;基础版&#xff09; 代码流程图 代码效果图 获取代码请关注MATLAB科研小白的个人公众号&#xff08;即文章下方二维码&#xff09;&#xff0c;并回复CEEMD去噪 本公众号致力于解决找代码难&#xff0c;写代…

卖家必看!亚马逊关联封店要怎么申诉?亚马逊防关联方法分享

不少亚马逊卖家为了能够提升产品销量&#xff0c;这个时候可能就会多开店铺&#xff0c;但是亚马逊会通过技术手段识别账号之间的关联性&#xff0c;一旦被检测到多个账号为同一卖家所有&#xff0c;这些账号就会被判定为关联&#xff0c;很多卖家遇到后都不知道怎么处理&#…

对象的生离死别

对象的生离死别 实验介绍 在构建一个类时&#xff0c;一般情况下需要编写构造函数、拷贝构造函数以及析构函数&#xff0c;这将直接影响程序的运行。而初始化列表是在调用构造函数时初始化参数的方式。 一个对象从实例化到销毁的历程&#xff1a; 知识点 内存分区构造函数exp…

IP定位数据可能不准的原因有哪些

IP定位数据可能不准的原因有多种&#xff0c;主要包括以下几个方面&#xff1a; 动态IP地址&#xff1a;一些互联网服务提供商(ISP)会为用户分配动态IP地址&#xff0c;这意味着用户的IP地址可能会随时间而变化。因此&#xff0c;数据库中的位置信息可能不时过时。 代理服务器…

视频如何提取文字?这四个方法一键提取视频文案

视频如何提取文字&#xff1f;你用过哪些视频提取工具&#xff1f;视频转文字工具&#xff0c;又称为语音识别软件&#xff0c;是一款能够将视频中的语音或对话转化为文字的实用工具。它运用了尖端的声音识别和语言理解技术&#xff0c;能精准地捕捉视频中的音频&#xff0c;并…

当视觉遇到毫米波雷达:自动驾驶的三维目标感知基准

​ 文章&#xff1a;Vision meets mmWave Radar: 3D Object Perception Benchmark for Autonomous Driving 作者: Yizhou Wang, Jen-Hao Cheng, Jui-Te Huang , Sheng-Yao Kuan , Qiqian Fu , Chiming Ni 编辑&#xff1a;点云PCL 欢迎各位加入知识星球&#xff0c;获取PDF…

Web安全-SQL注入【sqli靶场第11-14关】(三)

★★实战前置声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将其信息做其他用途&#xff0c;由用户承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 0、总体思路 先确认是否可以SQL注入&#xff0…

Q_GDW1819-2013电压监测装置协议结构解析

目录 一 专业术语二 基本功能2.1 基础功能2.2 数据存储2.3 显示功能&#xff08;设备能够看到的&#xff09;2.4 参数设置与查询2.5 事件检测与告警功能 三 其他内容3.1 通信方式3.2 通信串口 四 帧结构解析4.1 传输方式4.2 数据帧格式4.2.1 报文头&#xff08;2字节&#xff0…

wvp gb28181 pro 配置https访问

准备工作 必须要有域名。虽然数字证书也有ip证书,但是会很麻烦,多数ca机构验证服务器需要用到80或443端口,也就是必须先备案,所以最好还是使用域名证书。购买域名证书。根据安全级别要求自行配置。单域名(不支持通配符的),阿里云的域名都是可以免费申请的。完成域名到服…

2024美赛备战1--数据处理(数据预处理,异常值处理,预测模型,插值拟合 *****必看****)

1.数据预处理 所谓数据预处理&#xff0c;就是指在正式做题之前对数据进行的一些处理。在有些情 况下&#xff0c;出题方提供的数据或者网上查找的数据并不能直接使用&#xff0c;比如缺少数据甚 至是异常数据&#xff0c;如果直接忽略缺失值&#xff0c;或者没发现异常数据&am…

Axure RP 9 入门教程

1. Axure简介 Axure 是一个交互式原型设计工具&#xff0c;可以帮助用户创建复杂的交互式应用程序和网站。Axure 能够让用户快速构建出具有高度可交互性的原型&#xff0c;可以在团队中进行协作、分享和测试。 使用 Axure 可以设计出各种不同类型的原型&#xff0c;包括网站、移…

企业网站运营不稳定有什么影响

如果一个公司的网站打开都有困难&#xff0c;那么用户会对这个企业的实力产生怀疑&#xff0c;企业网站除了作为企业的名片外&#xff0c;更多的是承担增加企业交易订单的任务。因此很多网站会做有关的网络广告或者搜索引擎优化的工作。如果网站无法正常打开&#xff0c;那么用…

HNU计算机体系结构-实验3:多cache一致性算法

文章目录 实验3 多cache一致性算法一、实验目的二、实验说明三 实验内容1、cache一致性算法-监听法模拟2、cache一致性算法-目录法模拟 四、思考题五、实验总结 实验3 多cache一致性算法 一、实验目的 熟悉cache一致性模拟器&#xff08;监听法和目录法&#xff09;的使用&am…