一、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基本原理和使用的更多相关文章

  1. CountDownLatch CyclicBarrier和 Semaphore

    CountDownLatch CyclicBarrier和 Semaphore 原理 基于AQS实现. 让需要的暂时阻塞的线程,进入一个死循环里面,得到某个条件后再退出循环,以此实现阻塞当前线程的效果 ...

  2. CountDownLatch, CyclicBarrier and Semaphore

    Reference: [1] http://shazsterblog.blogspot.co.uk/2011/12/comparison-of-countdownlatch.html CountDow ...

  3. Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

    Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...

  4. 并发工具类:CountDownLatch、CyclicBarrier、Semaphore

    在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...

  5. Java并发(8):CountDownLatch、CyclicBarrier、Semaphore、Callable、Future

    CountDownLatch.CyclicBarrier.Semaphore.Callable.Future  都位于java.util.concurrent包下,其中CountDownLatch.C ...

  6. 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore

    前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...

  7. CountDownLatch、CyclicBarrier和Semaphore

    转载:http://www.cnblogs.com/dolphin0520/p/3920397.html 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDown ...

  8. 使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.C ...

  9. Java并发之CountDownLatch、CyclicBarrier和Semaphore

    CountDownLatch 是能使一组线程等另一组线程都跑完了再继续跑:CyclicBarrier 能够使一组线程在一个时间点上达到同步,可以是一起开始执行全部任务或者一部分任务. CountDow ...

随机推荐

  1. 学了两天 react,乱讲一下学习思路,顺便弄了一个脚手架

    之前一直用 vue 做一些小项目,最近接触了一个项目是用 react 做前端,虽然本身是做后端开发的,但是前端还是要了解一点的. 现在的项目基本上都是前后端分离的,后端就先不提了.前端的框架也是层出不 ...

  2. tomcat部署项目后,war包是否可刪?war包存在必要性!

    在tomcat中webapps目錄上傳war包后,  对war解压时候. war不能在tomcat运行时删除,否则会删除自动解压的工程. 你可以停止tomcat后删除war. 当你重新部署的时候,如果 ...

  3. c#实战开发:以太坊Geth 命令发布智能合约 (五)

    Token的合约代码我们参考Token-Factory的代码. 打开  https://remix.ethereum.org/#optimize=false&version=soljson-v ...

  4. Java并发编程实战 之 对象的共享

    上一篇介绍了如何通过同步多个线程避免同一时刻访问相同数据,本篇介绍如何共享和发布对象,使它们被安全地由多个进程访问. 1.可见性 通常,我们无法保证执行读操作的线程能看到其他线程写入的值,因为每个线程 ...

  5. RFID NFC

    RFID 和 NFC 的区别: ()NFC与RFID在物理层面看上去很相似,但实际上是两个完全不同的领域,因为RFID本质上属于识别技术,而NFC属于通信技术. ()NFC将非接触读卡器.非接触卡和点 ...

  6. css 半圆效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 设置input中placeholder的样式(placeholder设置字体)

    方法: 代码示例: .input::-webkit-input-placeholder { font-size: 3.73333333vw; color: #cccccc; } .input:-moz ...

  8. 升级Mac OS X上的git

    今天一打开visual studio code就提示我git版本low,需要升级,然后提供了一个下载链接(git官方下载地址:https://git-scm.com/),然后我就根据链接去下载了mac ...

  9. RuntimeException和Exception区别

    1.java将所有的错误封装为一个对象,其根本父类为Throwable, Throwable有两个子类:Error和Exception. 2.Error是Throwable 的子类,用于指示合理的应用 ...

  10. 在centos中搭建基于nginx的apt源服务器,整合yum源和apt源在一台服务器

    1.首先关闭防护墙或者设置规则通过且关闭selinux 2.nginx-1.14.2版本(编译安装)-自定义安装路径 3.开启nginx目录浏览 以上步骤请参考前文:https://www.cnblo ...