CountDownLatch、CyclicBarrier和Semaphore基本原理和使用
一、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基本原理和使用的更多相关文章
- CountDownLatch CyclicBarrier和 Semaphore
CountDownLatch CyclicBarrier和 Semaphore 原理 基于AQS实现. 让需要的暂时阻塞的线程,进入一个死循环里面,得到某个条件后再退出循环,以此实现阻塞当前线程的效果 ...
- CountDownLatch, CyclicBarrier and Semaphore
Reference: [1] http://shazsterblog.blogspot.co.uk/2011/12/comparison-of-countdownlatch.html CountDow ...
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- 并发工具类:CountDownLatch、CyclicBarrier、Semaphore
在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...
- Java并发(8):CountDownLatch、CyclicBarrier、Semaphore、Callable、Future
CountDownLatch.CyclicBarrier.Semaphore.Callable.Future 都位于java.util.concurrent包下,其中CountDownLatch.C ...
- 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore
前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...
- CountDownLatch、CyclicBarrier和Semaphore
转载:http://www.cnblogs.com/dolphin0520/p/3920397.html 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDown ...
- 使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.C ...
- Java并发之CountDownLatch、CyclicBarrier和Semaphore
CountDownLatch 是能使一组线程等另一组线程都跑完了再继续跑:CyclicBarrier 能够使一组线程在一个时间点上达到同步,可以是一起开始执行全部任务或者一部分任务. CountDow ...
随机推荐
- SmartSql Zookeeper分布式配置
安装 SmartSql.ZooKeeperConfig Install-Package SmartSql.ZooKeeperConfig Demo string connStr = "192 ...
- c# 抽象类,抽象方法使用(abstract)
入行一年多,在这个IT行业,开发技术主要使用的是.NET,而对应使用的高级语言自然就是c#了.从2017年7月入职后,在平时的工作过程中,只记得使用一些方法去完成逻辑功能,而很少去深究一些语法特性,特 ...
- C# 添加Word页眉、页脚和页码
在Word文档中,我们可以通过添加页眉.页脚的方式来丰富文档内容.添加页眉.页脚时,可以添加时间.日期.文档标题,文档引用信息.页码.内容解释.图片/LOGO等多种图文信息.同时也可根据需要调整文字或 ...
- 69道Spring面试题和答案,简单明了无套路
目录 Spring 概述 依赖注入 Spring beans Spring注解 Spring数据访问 Spring面向切面编程(AOP) Spring MVC Spring 概述 1. 什么是spri ...
- Java笔记(day7-day8)
this关键字: (1)this(当局部变量和成员变量重名时,可以用关键字this区分) this代表对象,当前对象 this就是所在函数所属对象的引用 简单来说,哪个对象 ...
- Java高阶语法---static
背景:听说static Java高阶语法是挺进BAT必经之路. static: 静态static,很多时候会令我望文生义,但是get到了static最重要的一点,其他的理解都还ok. static最重 ...
- 零基础学Python--------第11章 使用Python操作数据库
第11章 使用Python操作数据库 11.1 数据库编程接口 在项目开发中,数据库应用必不可少.虽然数据库的种类有很多,如SQLite.MySQL.Oracle等,但是它们的功能基本都是一样的,为了 ...
- Android为TV端助力 Linux命令查看包名类名
先运行apk 再输入logcat | grep START 查看当前启动apk的包名和类名 adb shell "pm list packages -f | grep com.yulong. ...
- Play vue.js with constant value in SailsJS
SailsJS supplies a utility module called parasails, which defines two elements, <ajax-form> an ...
- 卸载windows补丁
wusa /uninstall /kb: wusa /uninstall /kb: 和某些应用软件冲突时,需要将上述补丁卸载.