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你使用过吗的更多相关文章

  1. 【JUC】7.CountDownLatch

    Latch:门闩.一种线程通信的方式:当程序不涉及同步,仅仅需要线程通信的时候,使用synchronize或者lock的线程通信等待唤醒机制,就显得太重了: 这时候,可以考虑使用信号量类:CountD ...

  2. 并发教程--JAVA5中 计数信号量(Counting Semaphore)例子

    并发教程--JAVA5中 计数信号量(COUNTING SEMAPHORE)例子 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java中的计数信息量(C ...

  3. CountDownLatch和CycliBarrier介绍

    一.CountDownLatch 它被用来同步一个或多个任务,强制他们等待其他任务完成,这就是闭锁. public CountDownLatch(int count) { if (count < ...

  4. 多线程条件通行工具——CountDownLatch

    CountDownLatch的作用是,线程进入等待后,需要计数器达到0才能通行. CountDownLatch(int)构造方法,指定初始计数. await()等待计数减至0. await(long, ...

  5. 【Java并发编程实战】-----“J.U.C”:CountDownlatch

    上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...

  6. 同步辅助类CountDownLatch用法

    CountDownLatch是一个同步辅助类,犹如倒计时计数器,创建对象时通过构造方法设置初始值,调用CountDownLatch对象的await()方法则使当前线程处于等待状态,调用countDow ...

  7. 架构师养成记--12.Concurrent工具类CyclicBarrier和CountDownLatch

    java.util.concurrent.CyclicBarrier 一组线程共同等待,直到达到一个公共屏障点. 举个栗子,百米赛跑中,所有运动员都要等其他运动员都准备好后才能一起跑(假如没有发令员) ...

  8. Java并发之CountDownLatch

    CountDownLatch是Java concurrent包下的一个同步工具.它可以让一个(或多个)线程等待,直到其他线程中的某些操作完成. 本质上是一个信号量,我们把它比作一个有N个插销的大门,它 ...

  9. Java多线程之CountDownLatch学习

    给出官网上的例子:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html Java中conc ...

随机推荐

  1. c#Socket通讯

    参考http://bbs.cskin.net/thread-326-1-1.html的大神的代码 socket封装 /// <summary> /// 自定义Socket对象 /// &l ...

  2. PLSQL PL/SQL Developer Oracle 使用技巧 常用设置 卡顿问题 病毒防范( 附带:配置文件)

    相关工具版本: PL/SQL Developer: 9.0.4.1644 Oracle : Oracle Database 10g Enterprise Edition Release 10.2.0. ...

  3. 解决 VS Code「Code Runner」插件运行 python 时的中文乱码问题

    描述 这里整理了两种 VS Code「Code Runner」插件运行 python 时乱码的解决方案.至于设置「Auto Guess Encoding」为 true 的操作这里就不多描述了. 乱码截 ...

  4. 基于SAML2.0的SAP云产品Identity Authentication过程介绍

    SAP官网的架构图 https://cloudplatform.sap.com/scenarios/usecases/authentication.html 上图介绍了用户访问SAP云平台时经历的Au ...

  5. Delphi 定义线程对象

  6. mybatis-generator-gui

    mybatis-generator-gui介绍 mybatis-generator-gui是基于mybatis generator开发一款界面工具, 本工具可以使你非常容易及快速生成Mybatis的J ...

  7. SQL SERVER 常用函数 学习笔记

    1.字符串截取.字符串转数字 --Server.8.30 select SUBSTRING('SqlServer_2008',4,6) as DB, CONVERT(float,SUBSTRING(' ...

  8. 【转】char data[0]用法总结

    @2019-07-31 struct MyData { int nLen; ]; }; 开始没有理解红色部分的内容,上网搜索下,发现用处很大,记录下来. 在结构中,data是一个数组名:但该数组没有元 ...

  9. 03—Code First

           Code First模式我们称之为“代码优先”模式,使用Code First模式进行EF开发时开发人员只需要编写对应的数据类(其实就是领域模型的实现过程),然后自动生成数据库.这样设计的 ...

  10. ao的mobile解决方案

    http://aicdg.com/ue4-msaa-depth/ http://aicdg.com/vulkan-mass-shader-resolve/ ao两篇paper 分bake和realti ...