【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) {//创建CyclicBarrierCyclicBarrier 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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vite环境变量相关

环境变量&#xff1a;根据环境的不同&#xff0c;灵活的自动读取相应的变量。避免了手动修改。 import path from path import postCssPxToRem from postcss-pxtorem import { defineConfig, loadEnv } from vite import createVitePlugins from ./vite/plugins import copy f…

QT使用Socket与安卓Socket互发消息

背景:安卓设备通过usb网络共享给Linux,此时安卓设备与linux处于同一网络环境,符合使用socket的条件,linux做客户端,安卓做服务端 1.QT使用Socket (1).在工程文件中加入 QT network (2).导包以及写一些槽函数用做数据传输与状态接收 #ifndef MAINWINDOW_H #define MAINWINDOW…

Playwright UI 自动化测试实战

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

UI自动化测试(弹出框,多窗口)

一、弹出框实战 1、在UI自动化测试中经常会遇到Alert弹出框的场景。Alert类是对话框的处理&#xff0c;主要是对alert警告框。confirm确认框&#xff0c;promp消息对话框。 text():获取alert的文本 dismiss ():点击取消 accept():接受 send-keys():输入 from selenium import …

基于乌鸦算法优化概率神经网络PNN的分类预测 - 附代码

基于乌鸦算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于乌鸦算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于乌鸦优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

浅尝:iOS的CoreGraphics和Flutter的Canvas

iOS的CoreGraphic 基本就是创建一个自定义的UIView&#xff0c;然后重写drawRect方法&#xff0c;在此方法里使用UIGraphicsGetCurrentContext()来绘制目标图形和样式 #import <UIKit/UIKit.h>interface MyGraphicView : UIView endimplementation MyGraphicView// Onl…

一键帮您解决win11最新版画图工具难用问题!

&#x1f984;个人主页:修修修也 ⚙️操作环境:Windows 11 正文 自从win11更新后,新版的画图工具变得非常难用,如: 使用橡皮擦后露出背版马赛克 框住某部分拖动移动时背景露出马赛克剪贴板上图片信息无法直接插入到画图板 目前没有一个好一些的能够在软件内部解决这些问题的方…

浅聊汽车供应链数智化发展趋势

“2023中国汽车供应链大会暨第二届中国新能源智能网联汽车生态大会”在11月10日—12日&#xff0c;武汉经开区举办。围绕供应链安全与布局、新型汽车供应链打造、传统供应链升级、全球化发展等热点话题进行深入交流与探讨&#xff0c;寻找构建世界一流汽车供应链的对策、方法和…

virtualbox基本配置

全屏模式调出热键 右边的 ctrl home 键 安装增强功能 注意&#xff1a;virtualbox 自带那个安装增强功能点击后是没有效果的 1、启动虚拟机 2、设备 3、分配虚拟光驱 4、选择虚拟盘 5、选择对应iso文件&#xff0c;文件下载路径 6、双击对应文件安装&#xff0c;默认配置…

太好玩了,爬虫、部署API、加小程序,一条龙玩转知乎热榜

一直想做一个从爬虫到数据处理&#xff0c;到API部署&#xff0c;再到小程序展示的一条龙项目&#xff0c;最近抽了些时间&#xff0c;实现了一个关于知乎热榜的&#xff0c;今天就来分享一下&#xff01; 由于代码还没有完全整理好&#xff0c;今天只给出一个大致的思路和部分…

零一万物回应「抄袭 LLaMA」;京东原副总裁试用可穿戴人工喉丨 RTE 开发者日报 Vol.85

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

淘宝客APP源码/社交电商自营商城源码/前端基于Uniapp开发

淘宝客APP源码&#xff0c;前端基于Uniapp开发的社交电商自营商城源码。Thinkphp的后台&#xff0c;不是很标准&#xff0c;感兴趣的可以自行研究。 商城功能 1、首页基础装修&#xff1b;2、丰富选品库&#xff1b;3、淘口令解析&#xff1b;4、支持京东&#xff1b;5、支持…