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 ...
随机推荐
- 选项卡TAB
一.基础信息 关键class名:nav 写法: (1)头部选中状态:class="active" (2)头部按钮进行切换:<a>加data-toggle="t ...
- Abp 聚合测试
Abp 官网开始的教程例子,是IRpositoty<entity> 直接出现在应用层.但是如果是一个聚合根也会这样吗? 那么聚合根是访问仓储的最小单元,要通过聚合根来操作业务,就是实体, ...
- codeblocks 使用汇总
codeblocks 使用汇总 http://www.cnblogs.com/-clq/archive/2012/01/31/2333247.html
- 【shell脚本】字符串和数组的使用
字符串 可以使用单引号和双引号定义字符串变量但是单引号中不支持变量解析 #! /bin/bashusername="mayuan" str_1="hello ${user ...
- Linux设备驱动中的软件架构思想
目录 更新记录 一.Linux驱动的软件架构 1.1 出发点 1.2 分离思想 1.3 分层思想 二.platform设备驱动 2.1 platform设备 2.2 platform驱动 2.3 pl ...
- 许愿墙JQ
<!doctype html> <html> <head> <meta charset="utf-8"> <t ...
- 统一用户认证系统CUAS实现要点
背景: 基于目前存在多套员工使用的日常工作子系统,现状为各系统各自有一套用户体系,员工需要记住各系统的用户名.密码等信息,还需要登录多个系统,重复工作量颇多.统一用户认证组件将用户名.密码等信息统一存 ...
- 一个SAP顾问的回忆:我过去很胖!
去年也是这个时候,SAP成都研究院体育界大神邓阳,曾经赏脸在Jerry这个公众号上赐文一篇,介绍了他和围绕在他身边的一群小伙伴们的体育故事:SAP成都研究院的体育故事 而今天文章的主角则是SAP成都研 ...
- 自己整理的的数据操作DbHelper
using System.Data; using System.Data.SqlClient; using System.Configuration; namespace WindowsFormsAp ...
- C++中volatile
volatile只保证其“可见性”,不保证其“原子性”. 执行count++;这条语句由3条指令组成: (1)将 count 的值从内存加载到 cpu 的某个 寄存器r: (2)将 寄存器r 的值 + ...