CountDownLatch、CyclicBarrier和Semaphore基本原理和使用
一、CountDownLatch
CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。
比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。
CountDownLatch让一些线程阻塞知道另一些线程完成一系列操作后才被唤醒,CountDownLatch主要有两个方法,当一份或多个线程调用await方法时,调用线程会被阻塞。其他线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞),当计数器的值变为0时,因调用await方法被阻塞的线程会被唤醒,继续执行。
public class CountDownLatchDemo {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println("当前线程任务结束 : " + Thread.currentThread().getName());
countDownLatch.countDown();
}, String.valueOf(i)).start();
}
try {
// 等待其他线程执行完再执行
countDownLatch.await();
System.out.println("************全部执行结束***********");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出结果:
当前线程任务结束 : 0
当前线程任务结束 : 2
当前线程任务结束 : 3
当前线程任务结束 : 1
当前线程任务结束 : 4
当前线程任务结束 : 5
************全部执行结束***********
二、CyclicBarrier
CyclicBarrier的字面意思是可循环(Cyclic)使用的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法,当调用await()方法之后,线程就处于barrier了。
代码测试:收集七颗龙珠,召唤神龙。
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(7,
() -> {
System.out.println("**********召唤神龙**********");
});
for (int i = 1; i <= 7; i++){
new Thread(()->{
System.out.println("第" + Thread.currentThread().getName() + " 颗龙珠被收集");
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}, String.valueOf(i)).start();
}
}
}
输出结果:
第1 颗龙珠被收集
第7 颗龙珠被收集
第6 颗龙珠被收集
第5 颗龙珠被收集
第4 颗龙珠被收集
第3 颗龙珠被收集
第2 颗龙珠被收集
**********召唤神龙**********
三、Semaphore
Semaphore翻译成字面意思为信号量,Semaphore可以控同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个是用于并发线程数的控制。
代码实现小案例:6辆汽车抢夺3个停车位。
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++){
new Thread(()->{
try {
// 获取资源
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "号车获得停车位");
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "号车停车3秒离开停车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
// 释放资源
semaphore.release();
}
},String.valueOf(i)).start();
}
}
}
输出结果:
1号车获得停车位
3号车获得停车位
4号车获得停车位
4号车停车3秒离开停车位
3号车停车3秒离开停车位
5号车获得停车位
1号车停车3秒离开停车位
6号车获得停车位
2号车获得停车位
6号车停车3秒离开停车位
5号车停车3秒离开停车位
2号车停车3秒离开停车位 Process finished with exit code 0
CountDownLatch、CyclicBarrier和Semaphore基本原理和使用的更多相关文章
- CountDownLatch CyclicBarrier和 Semaphore
CountDownLatch CyclicBarrier和 Semaphore 原理 基于AQS实现. 让需要的暂时阻塞的线程,进入一个死循环里面,得到某个条件后再退出循环,以此实现阻塞当前线程的效果 ...
- CountDownLatch, CyclicBarrier and Semaphore
Reference: [1] http://shazsterblog.blogspot.co.uk/2011/12/comparison-of-countdownlatch.html CountDow ...
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- 并发工具类:CountDownLatch、CyclicBarrier、Semaphore
在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...
- Java并发(8):CountDownLatch、CyclicBarrier、Semaphore、Callable、Future
CountDownLatch.CyclicBarrier.Semaphore.Callable.Future 都位于java.util.concurrent包下,其中CountDownLatch.C ...
- 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore
前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...
- CountDownLatch、CyclicBarrier和Semaphore
转载:http://www.cnblogs.com/dolphin0520/p/3920397.html 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDown ...
- 使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.C ...
- Java并发之CountDownLatch、CyclicBarrier和Semaphore
CountDownLatch 是能使一组线程等另一组线程都跑完了再继续跑:CyclicBarrier 能够使一组线程在一个时间点上达到同步,可以是一起开始执行全部任务或者一部分任务. CountDow ...
随机推荐
- Python实战171202元组访问
学生信息系统中数据为固定格式: (名字,年龄,性别,邮箱地址,......) 学生数量很大为了减小存储开销,对每个学生信息用元组表示: ('jim',18,'male','jim8765@gmail. ...
- 基于 DataLakeAnalytics 做跨地域的数据分析
在阿里云上,很多客户的应用都是多地域部署的, 比如在北京(cn-beijing)的地域部署一个应用让北方的客户访问快一点,同时在杭州(cn-hangzhou)地域部署一份让南方的客户访问快一点.多地域 ...
- RequireJS入门级_RequireJS能给我们带来什么帮助?
前言:其实很早前就已经接触和了解到RequireJS了,当时只是大概明白它能用来控制JS的加载顺序,即:页面一定要先加载这个JS,再加载那个JS,对于RequireJS的好处还没有一个真正的体会和认识 ...
- 引用KBC.PetroSIM.Interop的dll,在代码中调用时出现 80040154 没有注册类 的错误
失败的尝试: regsvr32注册:模块已加载,但找不到入口点DllRegisterServer regasm注册:需写上regasm的完整路径,注册成功,但问题依旧 将项目的平台改为x86:问题依旧 ...
- 【网摘】C#中TransactionScope的使用方法和原理
时间 2013-08-12 19:59:34 51CTO推荐博文 原文 http://cnn237111.blog.51cto.com/2359144/1271600 在.net 1.1的时代,还 ...
- C# 实体类转json数据过滤掉字段为null的字段
C# 实体类转json数据过滤掉字段为null的字段 语法如下: var jsonSetting = new JsonSerializerSettings {NullValueHandling = N ...
- 命令模式 Command 行为型 设计模式(十八)
命令模式(Command) 请分析上图中这条命令的涉及到的角色以及执行过程,一种可能的理解方式是这样子的: 涉及角色为:大狗子和大狗子他妈 过程为:大狗子他妈角色 调用 大狗子的“回家吃饭”方法 引子 ...
- 解决vue数据渲染过程中的闪动问题
关键代码 主要解决vue双大括号{{}}在数据渲染和加载过程中的闪动问题,而影响客服体验. html代码: <span class="tableTitle selftab" ...
- SpringIOC/DI(2)
2019-03-08/09:24:37 开发环境:IDEA 1.创建Spring项目 File--New--project--Spring--Creat empty Spring-config.xml ...
- cesium 之地图显示坐标、比例尺、海拔高度效果篇(附源码下载)
前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 内 ...