同步工具:CountDownLatch、CyclicBarrier和Semaphore
1. CountDownLatch
1.1 功能及使用场景
一个同步工具,使得一个或多个线程等待一组线程执行完成后再执行。
使用场景:等待一些前置任务执行完成后,再执行特定的功能。比如,系统启动时,各种配置生效后,才能运行提供服务。
1.2 代码实例
public class CountDownLatchTest {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(10));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " end, " + System.currentTimeMillis());
latch.countDown();
}
}).start();
}
try {
System.out.println("main latch.await() " + System.currentTimeMillis());
latch.await();
System.out.println("main latch.await() end " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
特别注意:CountDownLatch初始化时,数量一定要等于等待的线程的数量。
2. CyclicBarrier
2.1 功能及使用场景
CyclicBarrier(可循环同步屏障),控制一组线程相互等待,直到所有线程都到达屏障点。所有线程都到达屏障点后,同时开始执行剩余的任务。
可循环,意味着当所有线程都到达屏障后,屏障可以被再次重复利用。
使用场景
多个任务同时到达某个临界情况时,才能同时执行剩余任务,否则相互等待。
2.2 示例代码
public class CyclicBarrierTest {
public static void main(String[] args) {
int num = 3;
final CyclicBarrier barrier = new CyclicBarrier(num);
for (int i = 0; i < num; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(Thread.currentThread().getName() + "执行结束,开始等待其它线程, " + System.currentTimeMillis());
barrier.await();
System.out.println(Thread.currentThread().getName() + "所有线程等待都执行完成,开始执行剩下任务, " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
}
// 屏障可以在上一次使用完成后被再次使用
for (int i = 0; i < num; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(Thread.currentThread().getName() + "执行结束,开始等待其它线程, " + System.currentTimeMillis());
barrier.await();
System.out.println(Thread.currentThread().getName() + "所有线程等待都执行完成,开始执行剩下任务, " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
}
System.out.println("main end at " + System.currentTimeMillis());
}
}
3. Semaphore
3.1 功能及使用场景
Semaphore(信号量),一个计数信号量。概念上,一个信号量维持了一个许可集合。
- acquire()方法:获取一个许可,如果没有获取到许可,则一直阻塞到获得一个许可;
- release()方法:归还一个许可。
实际上,并没有真正的许可对象,只是计数。
使用场景
限制资源同时被访问的线程数量
3.2 使用代码
public class SemaphoreTest {
public static void main(String[] args) {
final Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "尝试获取许可, " + System.currentTimeMillis());
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "获取许可, " + System.currentTimeMillis());
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(Thread.currentThread().getName() + "执行结束, " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}).start();
}
System.out.println("main end! " + System.currentTimeMillis());
}
}
特别注意:获得许可并执行完逻辑后,一定要释放,否则许可不会被归还。(有借有还,再借不难)
4. 总结
- CountDownLatch:一个任务等待前置任务执行完后才能执行
- CyclicBarrier: 一组任务相互等待,直到所有线程均到达某个临界状态
- Semaphore: 一组许可,控制资源被同时访问的数量(获取许可,也要归还许可)
同步工具:CountDownLatch、CyclicBarrier和Semaphore的更多相关文章
- 并发编程学习笔记(10)----并发工具类CyclicBarrier、Semaphore和Exchanger类的使用和原理
在jdk中,为并发编程提供了CyclicBarrier(栅栏),CountDownLatch(闭锁),Semaphore(信号量),Exchanger(数据交换)等工具类,我们在前面的学习中已经学习并 ...
- Java核心知识点学习----线程同步工具类,CyclicBarrier学习
线程同步工具类,CyclicBarrier日常开发较少涉及,这里只举一个例子,以做备注.N个人一块出去玩,相约去两个地方,CyclicBarrier的主要作用是等待所有人都汇合了,才往下一站出发. 1 ...
- CountDownLatch CyclicBarrier和 Semaphore
CountDownLatch CyclicBarrier和 Semaphore 原理 基于AQS实现. 让需要的暂时阻塞的线程,进入一个死循环里面,得到某个条件后再退出循环,以此实现阻塞当前线程的效果 ...
- Java并发和多线程4:使用通用同步工具CountDownLatch实现线程等待
CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown ...
- Java多线程_同步工具CountDownLatch
概念:CountDownLatch是多线程里面一个类似于计数器的高级同步工具,它的初始值代表线程的数量,当一个线程完成了任务后,CountDownLatch的值就减1,当值为0的时候,代表所有线程完成 ...
- CountDownLatch, CyclicBarrier and Semaphore
Reference: [1] http://shazsterblog.blogspot.co.uk/2011/12/comparison-of-countdownlatch.html CountDow ...
- java多线程系列9 高级同步工具(3) CyclicBarrier
CyclicBarrier 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point) 然后一再执行 public class CyclicBar ...
- 线程同步工具CountDownLatch
CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行.假如我们这个想要继续往下执行的任务调用一个CountDownLatc ...
- JAVA多线程提高十:同步工具CyclicBarrier与CountDownLatch
今天继续学习其它的同步工具:CyclicBarrier与CountDownLatch 一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公 ...
随机推荐
- springzuul本地路由和跨服务器路由问题
阿里云服务器在旧新服务迁移过程中,发现路由到认证中心找不到服务 解决办法: 在路由配置里面使用下面的配置 #zuul.routes.claimconf.path=/claimconf/**#zuul. ...
- 扫描Linux服务器查找恶意软件和rootkit的一款工具
官网参考官网安装教程:wget https://www.clamav.net/downloads/production/clamav-0.101.1.tar.gztar -zxvf clamav-0. ...
- 【Codeforces 1120C】Compress String
Codeforces 1120 C 题意:给一个串\(S\),将这个串分成\(t_1..t_m\),如果\(t_i\)在\(t_1..t_{i-1}\)中作为子串出现过,那么这个的代价是\(b\),否 ...
- 【Codeforces 113B】Petr#
Codeforces 113 B 题意:有一个母串\(S\)以及两个串\(S_{begin}\)和\(S_{end}\),问\(S\)中以\(S_{begin}\)为开头并且以\(S_{end}\)为 ...
- Java多线程编程模式实战指南一:Active Object模式(上)
Active Object模式简介 Active Object模式是一种异步编程模式.它通过对方法的调用与方法的执行进行解耦来提高并发性.若以任务的概念来说,Active Object模式的核心则是它 ...
- POJ3301 Texas Trip 计算几何、随机化贪心
传送门--Vjudge 三分写法似乎有问题,可以去Udebug上看Morass的\(666\)个测试点的数据,我的乱搞有很多比正解答案小,但还是能在SPOJ和POJ过,可见数据之水. 可以对正方形的角 ...
- CF797F Mice and Holes 贪心、栈维护DP
传送门 首先\(\sum c\)有些大,考虑将其缩小降低难度 考虑一个贪心:第一次所有老鼠都进入其左边第一个容量未满的洞(如果左边没有就进入右边第一个未满的洞),第二次所有老鼠都进入其右边第一个容量未 ...
- UOJ224 NOI2016 旷野大计算 构造、造计算机
传送门——UOJ 传送门——Luogu 这段时间请不要找Itst聊天,Itst已经做疯了 事实证明大模拟题不可做 query 1 送分,加起来一起乘即可 I I + < - O query 2 ...
- LOJ2538 PKUWC2018 Slay the Spire DP
传送门 不想放题面了,咕咕咕咕咕 这个期望明明是用来吓人的,其实要算的就是所有方案的最多伤害的和. 首先可以知道的是,能出强化牌就出强化牌(当然最后要留一张攻击牌出出去),且数字尽量大 所以说在强化牌 ...
- kafka学习2:kafka集群安装与配置
在前一篇:kafka学习1:kafka安装 中,我们安装了单机版的Kafka,而在实际应用中,不可能是单机版的应用,必定是以集群的方式出现.本篇介绍Kafka集群的安装过程: 一.准备工作 1.开通Z ...