CountDownLatch和CylicBarrier以及Semaphare你使用过吗
CountDownLatch
是什么
CountDownLatch的字面意思:倒计时 门栓
它的功能是:让一些线程阻塞直到另一些线程完成一系列操作后才唤醒。
它通过调用await方法让线程进入阻塞状态等待倒计时0时唤醒。
它通过线程调用countDown方法让倒计时中的计数器减去1,当计数器为0时,会唤醒哪些因为调用了await而阻塞的线程。
- 底层是使用AQS实现的
案例
假设老板开一个紧急会议,他先到会议室等着所有人签到然后开始开会,可以使用CountDownLatch进行模拟。
public static void main(String[] args) {
CountDownLatch countDownLatch=new CountDownLatch(5);
for (int i=1;i<=5;i++){
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"签到!");
countDownLatch.countDown();
},"第"+i+"個人").start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("老板宣布人夠了开始开会!");
}
运行结果:
//注意这里的签到顺序可以随意
第1個人签到!
第2個人签到!
第3個人签到!
第4個人签到!
第5個人签到!
老板宣布人夠了开始开会!
CyclicBarrier
是什么
CyclicBarrier [ˈsaɪklɪk] [ˈbæriər] 的字面意思:可循环使用的屏障 【栅栏】
它的功能是:让一组线程到达一个屏障时被阻塞,知道最后一个线程到达屏障,所有被屏障拦截的线程才会继续执行。
它通过调用await方法让线程进入屏障,
- 底层是通过ReentrantLock以及Condition中的await和signal实现
/** The lock for guarding barrier entry */
private final ReentrantLock lock = new ReentrantLock();
/** Condition to wait on until tripped */
private final Condition trip = lock.newCondition();
图例

例子
还是上面的开会的例子,我们使用CyclicBarrier实现。
public static void main(String[] args) {
CyclicBarrier cyclicBarrier=new CyclicBarrier(5,()->{
System.out.println("老板宣布人夠了开始开会!!");
});
for (int i=1;i<=5;i++){
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"签到!");
cyclicBarrier.await(); //如果等待的线程数未到,这里将一直等待
//等线程数够了下面语句将继续执行......
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},"第"+i+"個人").start();
}
}
运行结果:
第1個人签到!
第2個人签到!
第3個人签到!
第4個人签到!
第5個人签到!
老板宣布人夠了开始开会!!
Semaphor
是什么
Semaphor [ˈseməfɔːr] 信号量的意思;
它主要用于两个目的:
- 用于多个共享资源互斥使用。【也就是具有锁的功能】
一个停车场有多个停车位,这多个停车位对应汽车来说就是多个共享资源,Semaphor可以实现多个停车位和多个汽车之间的互斥。 - 用于控制并发线程数。(就是控制同时得到共享资源的线程数量)
在创建Semaphor时可以指定并发线程数,
//permits :允许
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
//还可以指定是否为公平锁
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
- 信号量为1时 相当于独占锁 信号量大于1时相当于共享锁。
例子
我们测试使用Semaphor实现控制线程并发访问方法。
/**
* 测试使用Semaphor信号量控制方法的访问
*/
public class TestSemaphor {
Semaphore semaphore=new Semaphore(5);
/**
* 假设并发只能为5个
*/
public void pay(){
try {
//在 semaphore.acquire() 和 semaphore.release()之间的代码,同一时刻只允许指定个数的线程进入!
semaphore.acquire();
System.out.println("这是支付的方法!");
Thread.sleep(2000);
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TestSemaphor ts=new TestSemaphor();
for (int i=0;i<10;i++){
new Thread(()->{
ts.pay();
},"线程"+i).start();
}
}
}
运行效果:
线程0这是支付的方法!
线程3这是支付的方法!
线程6这是支付的方法!
线程5这是支付的方法!
线程1这是支付的方法!
//注意这里是执行的暂停点
线程7这是支付的方法!
线程8这是支付的方法!
线程2这是支付的方法!
线程4这是支付的方法!
线程9这是支付的方法!
注意结果:10个线程分了两批执行的,也就是说我们控制了访问pay方法的线程数量,每次并发只能是5个!
CountDownlatch和CyclicBarrier以及Semaphor的区别是
CountDownLatch是做减法,CyclicBarrier是做加法,Semaphor的临界资源可以反复使用
CountDownLatch不能重置计数,CycliBarrier提供的reset()方法可以重置计数,不过只能等到第一个计数结束。Semaphor可以重复使用。
CountDownLatch和CycliBarrier不能控制并发线程的数量,Semaphor可以实现控制并发线程的数量。
资源
CountDownLatch和CylicBarrier以及Semaphare你使用过吗的更多相关文章
- 【JUC】7.CountDownLatch
Latch:门闩.一种线程通信的方式:当程序不涉及同步,仅仅需要线程通信的时候,使用synchronize或者lock的线程通信等待唤醒机制,就显得太重了: 这时候,可以考虑使用信号量类:CountD ...
- 并发教程--JAVA5中 计数信号量(Counting Semaphore)例子
并发教程--JAVA5中 计数信号量(COUNTING SEMAPHORE)例子 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java中的计数信息量(C ...
- CountDownLatch和CycliBarrier介绍
一.CountDownLatch 它被用来同步一个或多个任务,强制他们等待其他任务完成,这就是闭锁. public CountDownLatch(int count) { if (count < ...
- 多线程条件通行工具——CountDownLatch
CountDownLatch的作用是,线程进入等待后,需要计数器达到0才能通行. CountDownLatch(int)构造方法,指定初始计数. await()等待计数减至0. await(long, ...
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...
- 同步辅助类CountDownLatch用法
CountDownLatch是一个同步辅助类,犹如倒计时计数器,创建对象时通过构造方法设置初始值,调用CountDownLatch对象的await()方法则使当前线程处于等待状态,调用countDow ...
- 架构师养成记--12.Concurrent工具类CyclicBarrier和CountDownLatch
java.util.concurrent.CyclicBarrier 一组线程共同等待,直到达到一个公共屏障点. 举个栗子,百米赛跑中,所有运动员都要等其他运动员都准备好后才能一起跑(假如没有发令员) ...
- Java并发之CountDownLatch
CountDownLatch是Java concurrent包下的一个同步工具.它可以让一个(或多个)线程等待,直到其他线程中的某些操作完成. 本质上是一个信号量,我们把它比作一个有N个插销的大门,它 ...
- Java多线程之CountDownLatch学习
给出官网上的例子:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html Java中conc ...
随机推荐
- 13 Msql之四种事务隔离界别
一.事务的基本要素 1.原子性:事务开始后的所有操作,要么全部做完,要么全部不做,不能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没发生一样.也就是说事务是一个不可分割 ...
- vue中的绑定class和微信小程序中的绑定class的区别
微信小程序 小程序里面的class与style绑定,遵循HTML特性绑定,有关于HTML绑定.在进行class与style绑定时,可以直接绑定,也可以带上逻辑与,或者三元运算进行条件控制 JS dat ...
- oracel数据泵导出导入
Oracle11g 使用数据泵导入/导出数据 expdp/impdp 目标:使用oracle数据泵,将A电脑上的数据库databaseA导出后,再导入到B电脑上的数据库databaseB中. A电脑上 ...
- QT版本下载链接
http://download.qt.io/archive/qt/
- 微信小程序双向绑定
欢迎加入前端交流群交流知识获取视频资料:749539640 vue.angular的双向绑定如下示例: <div> <input type="text" [(ng ...
- python异步编程 (转载)
Python Async/Await入门指南 转自:https://zhuanlan.zhihu.com/p/27258289 本文将会讲述Python 3.5之后出现的async/await的使 ...
- Nexus Repository Manager OSS 2 配置阿里云私服做代理的坑
安装 搭建 Nexus 私服很简单,官网下载,解压: 使用管理员权限打开cmd: > cd nexus---bundle\nexus--\bin > nexus.bat install # ...
- hibernate入门配置及第一个hibernate程序
学习了hibernate后就想先给大家分享一下它的配置方法: jar包导入 一.数据库表的创建 二.开启hibernate配置 编译器:eclipse 数据库:mysql 1.创建第一个xml文件 ...
- TensorFlow中numpy与tensor数据相互转化
numpy与tensor数据相互转化: *Numpy2Tensor 虽然TensorFlow网络在输入Numpy数据时会自动转换为Tensor来处理,但是我们自己也可以去显式的转换: data_ten ...
- mysql锁定单个表的方法
mysql锁定单个表的方法mysql>lock table userstat read;mysql>unlock tables; 本文来自ChinaUnix博客,如果查看原文请点:http ...