05_JUC强大的辅助类
JUC的多线程辅助类非常多,这里我们介绍三个:
CountDownLatch(倒计数器)
CyclicBarrier(循环栅栏)
Semaphore(信号量)
1. CountDownLatch
CountDownLatch是一个非常实用的多线程控制工具类,应用非常广泛。
例如:在手机上安装一个应用程序,假如需要5个子进程检查服务授权,那么主进程会维护一个计数器,初始计数就是5。用户每同意一个授权该计数器减1,当计数减为0时,主进程才启动,否则就只有阻塞等待了。
CountDownLatch中count down是倒数的意思,latch则是门闩的含义。整体含义可以理解为倒数的门栓,似乎有一点“三二一,芝麻开门”的感觉。CountDownLatch的作用也是如此。
常用的就下面几个方法:
new CountDownLatch(int count) //实例化一个倒计数器,count指定初始计数
countDown() // 每调用一次,计数减一
await() //等待,当计数减到0时,阻塞线程(可以是一个,也可以是多个)并行执行
案例:6个同学陆续离开教室后值班同学才可以关门。
public class CountDownLatchDemo {/*** main方法也是一个进程,在这里是主进程,即上锁的同学** @param args*/public static void main(String[] args) throws InterruptedException {// 初始化计数器,初始计数为6CountDownLatch countDownLatch = new CountDownLatch(6);for (int i = 0; i < 6; i++) {new Thread(()->{try {// 每个同学墨迹几秒钟TimeUnit.SECONDS.sleep(new Random().nextInt(5));System.out.println(Thread.currentThread().getName() + " 同学出门了");// 调用countDown()计算减1countDownLatch.countDown();} catch (InterruptedException e) {e.printStackTrace();}}, String.valueOf(i)).start();}// 调用计算器的await方法,等待6位同学都出来countDownLatch.await();System.out.println("值班同学锁门了");}
}
2. CyclicBarrier
从字面上的意思可以知道,这个类的中文意思是“循环栅栏”。大概的意思就是一个可循环利用的屏障。该命令只在每个屏障点运行一次。若在所有参与线程之前更新共享状态,此屏障操作很有用。
常用方法:
CyclicBarrier(int parties, Runnable barrierAction) 创建一个CyclicBarrier实例,parties指定参与相互等待的线程数,barrierAction一个可选的Runnable命令,该命令只在每个屏障点运行一次,可以在执行后续业务之前共享状态。该操作由最后一个进入屏障点的线程执行。
CyclicBarrier(int parties) 创建一个CyclicBarrier实例,parties指定参与相互等待的线程数。
await() 该方法被调用时表示当前线程已经到达屏障点,当前线程阻塞进入休眠状态,直到所有线程都到达屏障点,当前线程才会被唤醒。
案例:组队打boss过关卡游戏。
注意:所有的"过关了"都是由最后到达await方法的线程执行打印的。
public class CyclicBarrierDemo {public static void main(String[] args) {CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {System.out.println(Thread.currentThread().getName() + " 过关了");});for (int i = 0; i < 3; i++) {new Thread(()->{try {System.out.println(Thread.currentThread().getName() + " 开始第一关");TimeUnit.SECONDS.sleep(new Random().nextInt(4));System.out.println(Thread.currentThread().getName() + " 开始打boss");cyclicBarrier.await();System.out.println(Thread.currentThread().getName() + " 开始第二关");TimeUnit.SECONDS.sleep(new Random().nextInt(4));System.out.println(Thread.currentThread().getName() + " 开始打boss");cyclicBarrier.await();System.out.println(Thread.currentThread().getName() + " 开始第三关");TimeUnit.SECONDS.sleep(new Random().nextInt(4));System.out.println(Thread.currentThread().getName() + " 开始打boss");cyclicBarrier.await();} catch (Exception e) {e.printStackTrace();}}, String.valueOf(i)).start();}}
}
3. Semaphore
Semaphore翻译成字面意思为 信号量,Semaphore可以控制同时访问的线程个数。非常适合需求量大,而资源又很紧张的情况。比如给定一个资源数目有限的资源池,假设资源数目为N,每一个线程均可获取一个资源,但是当资源分配完毕时,后来线程需要阻塞等待,直到前面已持有资源的线程释放资源之后才能继续。
常用方法:
public Semaphore(int permits) // 构造方法,permits指资源数目(信号量)
public void acquire() throws InterruptedException // 占用资源,当一个线程调用acquire操作时,它要么通过成功获取信号量(信号量减1),要么一直等下去,直到有线程释放信号量,或超时。
public void release() // (释放)实际上会将信号量的值加1,然后唤醒等待的线程。
信号量主要用于两个目的:
多个共享资源的互斥使用。
用于并发线程数的控制。保护一个关键部分不要一次输入超过N个线程。
案例:6辆车抢占3个车位
public class SemaphoreDemo {public static void main(String[] args) {// 初始化信号量,3个车位Semaphore semaphore = new Semaphore(3);// 6个线程,模拟6辆车for (int i = 0; i < 6; i++) {new Thread(()->{try {// 抢占一个停车位semaphore.acquire();System.out.println(Thread.currentThread().getName() + " 抢到了一个停车位!!");// 停一会儿车TimeUnit.SECONDS.sleep(new Random().nextInt(10));System.out.println(Thread.currentThread().getName() + " 离开停车位!!");// 开走,释放一个停车位semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}}, String.valueOf(i)).start();}}
}
05_JUC强大的辅助类相关推荐
- Eureka的InstanceInfoReplicator类(服务注册辅助工具)
关于服务注册 以下图片来自Netflix官方,图中显示Eureka Client会向注册中心发起Get Registry请求来获取服务列表: 以Spring Cloud的Edgware.RELEASE ...
- Java中使用JCOM操作Word/Excel对象
通过使用COM技术,我们用微软Office应用程序能够建立很多应用程序扩展,但是Java开发人员却无法享受它带来的便利--除非他们拥有方便的Java访问COM的途径(Java-to-COM桥).使用J ...
- Java线程(五):Executors、ThreadFactory
Executors public class Executors 一个功能非常强大的辅助类. 此包中所定义的 Executor.ExecutorService.ScheduledExecutorSer ...
- 大数据学习之路 JUC篇
大数据学习之路 JUC篇(1) 前提说明 本人是一名学生,茫茫it行业的一名卑微的小白,这是我第一次写博客.其原因是学着学着知识发现回顾的时候差不多全忘记了!!为了总结.复习自己以往学到过的有关大数据 ...
- android app数据存储,基于Android开发的APP数据存储研究
谢原武+龙文 摘要: 作为一个完整的应用程序,数据存储操作是必不可少的.Android系统一共提供了四种数据存储方式分别为File文件存储.Shared Preferences存储.ContentPr ...
- 尚硅谷宋红康2021JUC
一. JUC概述 什么是JUC? (1)java并发编程包中的一些工具类,这些工具类可以更加方便实现并发编程操作. (2)JUC 就是 java.util .concurrent 工具包的简称.这是一 ...
- JUC基础(周阳老师笔记
目录 一.JMM 1.volatile 2.加载代码练习: 二.JUC基础 1.什么是进程/线程,并发/并行 进程/线程 并发/并行 2.线程的状态 3.线程 操作 资源类 4.Lambda表达式 j ...
- JUC 2020 周阳 尚硅谷 学习笔记
这里写目录标题 一 JUC 介绍 1 进程线程介绍介绍 2 并发并行的介绍 3 wait 和 sleep的区别 4 线程的状态 二 卖票算法的企业级模板实现 企业级简单实现(synchronized) ...
- JUC笔记之尚硅谷周阳老师思维导图整理
文章目录 1. JUC 是什么 2. Lock 接口 3. Lambda表达式复习--详情请看 on java 8 4. 线程间通信 5. 线程间定制化调用通信 6.NotSafeDemo 7.多线程 ...
最新文章
- 网站外部链接优化如何进一步提升?
- .NET Core使用EF分页查询数据报错:OFFSET语法错误问题
- java 捕获特定异常_java – 使用特定消息捕获异常
- web安全day48:session和cookie、同源策略的初步理解
- 学习笔记(1):《微电子器件》陈星弼(第四版)第1章 半导体物理基础及基本方程
- 主播被MCN解约并判违约金60万
- GPS基带P码处理总结——FPGA实现的关键点
- CAS单点登录:CAS客户端搭建(整合Shiro和Spring Boot)
- python for循环求1到100的和_python如何计算1到100的和(用for循环)
- IDEA 2018.3.3 有效期至 2100
- 2017ACM-ICPC亚洲区域赛(西安站)
- 【汇正财经】什么是板块轮动?有什么规律?
- import cv2 报错(linux环境)ImportError: libGL.so.1: cannot open shared object file: No such file or direc
- 给iOS App减肥
- Variant数据类型
- 语音信号处理第三章:
- Http Header里的Content-Type
- 习题:有100个学生种100棵树,其中高中生每人种3棵树,初中生每人种1棵树,小学生每3人种1棵树,问高中生、初中生、小学生各有多少人?
- Oracle ORA-01017: invalid username/password;解决完一个12560又来一个
- 计算机 打印机型号编码不可用,打印机型号编码显示不可用