【JUC】六、辅助类

文章目录

  • 1、CountDownLatch减少计数
  • 2、CyclicBarrier循环栅栏
  • 3、Semaphore信号灯

本篇整理JUC的几个同步辅助类:

  • 减少计数:CountDownLatch
  • 循环栅栏:CyclicBarrier
  • 信号灯:Semaphore

1、CountDownLatch减少计数

案例:6个同学陆续离开教室后,班长才可以锁门

先不使用CountDownLatch,看下效果:

public class CountDownDemo {

    public static void main(String[] args) {
       
        for (int i = 1; i < 7; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "号同学离开了教室");
            },String.valueOf(i)).start();
        }
        System.out.println(Thread.currentThread().getName() + " 班长锁门走人了");
    }
}

运行:这里循环执行6次start,创建6个就绪状态的线程后,main线程继续向下执行,而这6个新线程还要抢夺CPU时间片、执行,因此可能出现其他线程未执行结束,main线程(班长)就执行结束的情况。(先main线程中start创建线程,再抢时间片,抢到后才执行run方法,不要迷)

在这里插入图片描述

改进,引入CountDownLatch:

public class CountDownDemo {

    public static void main(String[] args) throws InterruptedException {
        //创建CountDownLatch对象,设置初始值
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i < 7; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "号同学离开了教室");
                //计数减一(因为到这儿,新线程的run方法也执行完了)
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        //计数器未成0前,让当前线程(main线程)挂起
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + " 班长锁门走人了");
    }
}

在这里插入图片描述

CountDownLatch类的常用方法

  • 构造器方法,传入初始的计数
CountDownLatch(int count)
  • 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断
void await()
  • 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间
boolean await(long timeout, TimeUnit unit)
  • 锁存器计数减一
void countDown()
  • 返回当前计数
long getCount()

总结

  • 定义计数器初始值
  • 每次相关操作后,让计数器减一
  • 计数器的值没变成0 ,当前线程就一直await,等计数器变成0后,await后面的代码才会继续执行

2、CyclicBarrier循环栅栏

作用

让一组线程互相等待,直到达到某个公共的屏障点。且可以在达到这个公共屏障点后(在一组线程中的最后一个线程到达之后,但在释放所有线程之前)执行一个Runnable。注意不是新开一个线程去执行,而是由最后一个进入 barrier 的线程执行。

案例:集齐7颗龙珠才可以召唤神龙

public class CyclicDemo {

    //设置固定值
    private static final int NUMBER = 7;

    public static void main(String[] args) {
        //创建CyclicBarrier
        CyclicBarrier cyclicBarrier = new CyclicBarrier(NUMBER, () -> {
            System.out.println("集齐7颗龙珠,召唤神龙成功!");
        });
        //集齐七颗龙珠的过程
        for (int i = 1; i <= 7 ; i++) {
            new Thread(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + "星龙珠被收集到了");
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }

    }
}

运行:

在这里插入图片描述

修改参数,让for循环跑6次(即只创建6个线程去调用await,刻意不让其到达number),而number仍然为7,此时运行,程序一直等待,最后exit -1

在这里插入图片描述
CyclicBarrier类的常用方法

  • 构造方法,传入参与线程的数量,和最后要执行的操作
CyclicBarrier(int parties, Runnable barrierAction)
  • 在所有参与线程未调用CyclicBarrier对象的await方法之前,将一直等待,也就是上面演示的达到不了那个number。这些参与的线程,在其最后调用await,就相当于在说我已在当前屏障出等待。而若有参与线程不调用await,就像春游发车前少个人一样,只能整个线程组都等着。
int await()
  • 同上,未到屏障点前,所有调用了await的线程(参与线程)就一直等待,除非到了超时时间
await(long timeout, TimeUnit unit)
  • 返回当前已到达屏障点的线程的数量(春游实际到上车点的人数)
int getNumberWaiting()
  • 返回传入的屏障点(春游报名人数)
int getParties()

总结

Barrier,屏障,参与的线程调一次await,即说明该线程已在屏障出等待,屏障点+1,达到这个屏障点,线程组的所有线程才继续往下执行,否则之前调用了await方法的线程就一直处于await等待状态,除非到了指定的超时时间

3、Semaphore信号灯

作用

维护一个信号量,这个信号量里有多个许可,拿到许可就执行,没拿到就等着。有点像对象锁了,而和对象锁不同的是,一个对象,一把对象锁,但Semaphore的这个锁(许可)的数量是你自己传入的。

案例:6辆汽车,停三个停车位

车停在车位A,其他车就不能再停在A位了,这就是获取一个许可。车开出去,就是释放一个许可

acquire获取许可证后,其他线程只能一直等待,阻塞状态

public class SemaphoreDemo {

    public static void main(String[] args) {
        //创建Semaphore,设置许可数量,三个车位,对应三个许可证
        Semaphore semaphore = new Semaphore(3);
        //模拟6辆汽车
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                try {
                    //抢占许可证
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "抢到了车位");
                    //设置一个5s以内的随机时间,模拟停车
                    TimeUnit.SECONDS.sleep(new Random().nextInt(5));
                    System.out.println(Thread.currentThread().getName() + "=====> 离开了车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //释放许可
                    semaphore.release();
                }
            },String.valueOf(i)).start();


        }
    }
}

运行:

在这里插入图片描述

Semaphore类的常用方法

  • 构造方法,传入一个数字,如果把Semaphore类看成我们前面并发编程步骤里的资源类,那这个数字就是设置有几把对象锁
Semaphore(int permits)
  • 构造方法重载,可传入一个Boolean,表示是否公平的给许可证,设置false时,是允许新启动的线程插队的,设置为true,则按照先进先出的方式来在等待的线程队列中选择线程,发放许可
Semaphore(int permits, boolean fair)
  • 获取许可
void acquire()
  • 释放许可
void release()

在这里插入图片描述

总结

个人理解就是,如果把Semaphore类看成我们前面并发编程步骤里的资源类,那它特殊的地方就是,这个资源类的一个对象有几把对象锁,是我们可以自己在构造方法里设置的,而普通的自定义资源类,想要n把对象锁,就得new上n个对象。


最后,API文档地址:https://tool.oschina.net/apidocs/apidoc?api=jdk-zh

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

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

相关文章

基于opencv+tensorflow+神经网络的智能银行卡卡号识别系统——深度学习算法应用(含python、模型源码)+数据集(二)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 训练集图片处理1&#xff09;数据加载2&#xff09;图像处理 2. 测试图片处理1&#xff09;图像读取2&#xff09;图像处理 相关其它博客工程源代码下载其它资料下载 前言 本项目基于从网络获取的多种银行卡数据…

政府指导89元保330万 “聊惠保”2024年度正式上线!

11月15日&#xff0c;“聊惠保”2024年度启动仪式在聊城市融媒体中心举行。市政府领导&#xff0c;省直、市直相关部门单位和共保体成员单位负责同志参加仪式。“聊惠保”2024年度正式上线&#xff01;“聊惠保”项目组为聊城市医疗救助困难群体捐赠“聊惠保”2024年度团体保险…

python基础练习题库实验八

文章目录 前言题目1代码 题目2代码 题目3代码 总结 前言 &#x1f388;关于python小题库的这模块我已经两年半左右没有更新了&#xff0c;主要是在实习跟考研&#xff0c;目前已经上岸武汉某211计算机&#xff0c;目前重新学习这门课程&#xff0c;也做了一些新的题目 &#x…

LeetCode34-34. 在排序数组中查找元素的第一个和最后一个位置

&#x1f517;:代码随想录:二分查找的算法讲解:有关left<right和left<right的区别 class Solution {public int[] searchRange(int[] nums, int target) {int nnums.length;int l0,hn-1;if(numsnull){return null; }if(n0){return new int[]{-1,-1}; }if(target&l…

阿里云99元ECS云服务器老用户也能买,续费同价!

阿里云近日宣布了2023年的服务器优惠活动&#xff0c;令用户们振奋不已。最引人瞩目的消息是&#xff0c;阿里云放开了老用户的购买资格&#xff0c;99元服务器也可以供老用户购买&#xff0c;并且享受续费的99元优惠。此外&#xff0c;阿里云还推出了ECS经济型e实例&#xff0…

8年经验的软件工程师建议

我希望在职业生涯早期就开始做的事情和我希望以不同的方式做的事情。 大家好&#xff0c;我已经做了八年半的软件工程师。这篇文章来源于我最近对自己在职业生涯中希望早点开始做的事情以及希望以不同方式做的事情的自我反思。 我在这里分享的对任何希望提高和进步到高级甚至…

Java远程操作Linux服务器命令

Java可以通过SSH协议远程连接Linux服务器&#xff0c;然后使用JSch库或者Apache Commons Net库来执行远程Linux命令。以下是一个使用JSch库的示例代码&#xff1a; import com.jcraft.jsch.*;public class RemoteCommandExecutor {private String host;private String user;pr…

2023年亚太杯数学建模思路 - 复盘:人力资源安排的最优化模型

文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 描述 …

ubuntu 20通过docker安装onlyoffice,并配置https访问

目录 一、安装docker &#xff08;一&#xff09;更新包列表和安装依赖项 &#xff08;二&#xff09;添加Docker的官方GPG密钥 &#xff08;三&#xff09;添加Docker存储库 &#xff08;四&#xff09;安装Docker &#xff08;五&#xff09;启动Docker服务并设置它随系…

2024年上半年:加密领域迎来无限机遇与重大突破!

2024年上半年将成为加密行业发展的关键时期&#xff0c;一系列重大事件和计划将为这一领域带来深远的影响。这些举措不仅有望吸引更多机构投资者和资金流入加密市场&#xff0c;还将进一步提升比特币的认可度和流动性&#xff0c;推动整个行业迈向新的阶段。 SEC批准比特币现货…

消息通讯——MQTT WebHookSpringBoot案例

目录 EMQX WebHook介绍EMQX WebHook是什么EMQX WebHook配置项如何使用EMQX WebHook配置WebHook配置事件推送参数详解 SpringBoot集成Webhook实现客户端断连监控1. 实现前提2. 代码实现接口3. 监听结果 总结 EMQX WebHook介绍 EMQX WebHook是什么 EMQX WebHook 是由 emqx_web_…

大语言模型概述|亚马逊这些互联网公司为什么花巨资训练自己的模型?

2023年可谓是大语言模型元年&#xff0c;OpenAI、亚马逊、谷歌等互联网公司争先恐后推出了自己的大语言模型&#xff1a;GPT-4、Titan、PaLM 2&#xff0c;还有亚马逊即将推出的第二个大语言模型Olympus等等。这一革命性技术如今已经在全球范围内引发了广泛的讨论和关注&#x…

保姆级fastDFS安装教程

一、软件准备 环境需要准备四个包&#xff0c;分别是&#xff1a; 1. libfastcommon_1.0.36 2. FastdfsFastdfs_v5.11 3. fastdfs-nginx-module5.11 4. nginxnginx-1.12.2 二、环境准备 安装perl环境&#xff0c;后续编译fastdfs会用到 yum -y install perl* yum -y ins…

Python武器库开发-flask篇之URL重定向(二十三)

flask篇之URL重定向(二十三) 通过url_for()函数构造动态的URL&#xff1a; 我们在flask之中不仅仅是可以匹配静态的URL&#xff0c;还可以通过url_for()这个函数构造动态的URL from flask import Flask from flask import url_forapp Flask(__name__)app.route(/) def inde…

为忙碌的软件工程师精心准备的编码面试准备材料,超过 100,000 人受益!

这是一个针对技术面试准备的手册。它收集了大量的面试问题和答案&#xff0c;涵盖了算法、系统设计、前端等主题&#xff0c;并且还在不断更新和完善中。 这个项目是“Tech Interview Handbook”&#xff0c;解决了求职者在技术面试中遇到的各种难题&#xff0c;帮助他们更好地…

Jenkins的一些其他操作

Jenkins的一些其他操作 1、代码仓库Gogs的搭建与配置 Gogs 是一款极易搭建的自助 Git 服务&#xff0c;它的目标在于打造一个最简单、快速和轻松的方式搭建 Git 服务。使用 Go 语言开发的它能够通过独立的二进制进行分发&#xff0c;支持了 Go 语言支持的所有平台&#xff0…

vivado产生报告阅读分析-Report Power4

在布线后会生成“ Power Report ” &#xff08; 功耗报告 &#xff09;&#xff0c; 它基于当前器件工作条件和设计的切换率来报告功耗详情。功耗分析要求网表已完成综合或设计已完成布局布线。 • set_operating_conditions 命令用于设置工作条件。 • set_switching_ac…

【深度学习】SimSwap: An Efficient Framework For High Fidelity Face Swapping 换脸,实战

代码&#xff1a;https://github.com/neuralchen/SimSwap 文章目录 摘要介绍RELATED WORK实验结论代码实操 SimSwap是一个高保真度人脸交换的高效框架。它将源脸的身份转移到目标脸上&#xff0c;同时保留目标脸的属性。该框架包括ID注入模块&#xff08;IIM&#xff09;&#…

【Python基础篇】标识符

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录 一 Python中的标识符二 Python中常见的关键字三 合法的标识符 一 Python中的标识符 定义&…

计算机视觉的应用16-基于pytorch框架搭建的注意力机制,在汽车品牌与型号分类识别的应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用16-基于pytorch框架搭建的注意力机制&#xff0c;在汽车品牌与型号分类识别的应用&#xff0c;该项目主要引导大家使用pytorch深度学习框架&#xff0c;并熟悉注意力机制模型的搭建&#xff0c;这个…