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 ...
随机推荐
- c#Socket通讯
参考http://bbs.cskin.net/thread-326-1-1.html的大神的代码 socket封装 /// <summary> /// 自定义Socket对象 /// &l ...
- PLSQL PL/SQL Developer Oracle 使用技巧 常用设置 卡顿问题 病毒防范( 附带:配置文件)
相关工具版本: PL/SQL Developer: 9.0.4.1644 Oracle : Oracle Database 10g Enterprise Edition Release 10.2.0. ...
- 解决 VS Code「Code Runner」插件运行 python 时的中文乱码问题
描述 这里整理了两种 VS Code「Code Runner」插件运行 python 时乱码的解决方案.至于设置「Auto Guess Encoding」为 true 的操作这里就不多描述了. 乱码截 ...
- 基于SAML2.0的SAP云产品Identity Authentication过程介绍
SAP官网的架构图 https://cloudplatform.sap.com/scenarios/usecases/authentication.html 上图介绍了用户访问SAP云平台时经历的Au ...
- Delphi 定义线程对象
- mybatis-generator-gui
mybatis-generator-gui介绍 mybatis-generator-gui是基于mybatis generator开发一款界面工具, 本工具可以使你非常容易及快速生成Mybatis的J ...
- SQL SERVER 常用函数 学习笔记
1.字符串截取.字符串转数字 --Server.8.30 select SUBSTRING('SqlServer_2008',4,6) as DB, CONVERT(float,SUBSTRING(' ...
- 【转】char data[0]用法总结
@2019-07-31 struct MyData { int nLen; ]; }; 开始没有理解红色部分的内容,上网搜索下,发现用处很大,记录下来. 在结构中,data是一个数组名:但该数组没有元 ...
- 03—Code First
Code First模式我们称之为“代码优先”模式,使用Code First模式进行EF开发时开发人员只需要编写对应的数据类(其实就是领域模型的实现过程),然后自动生成数据库.这样设计的 ...
- ao的mobile解决方案
http://aicdg.com/ue4-msaa-depth/ http://aicdg.com/vulkan-mass-shader-resolve/ ao两篇paper 分bake和realti ...