同步工具: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是一个同步辅助类,它允许一组线程互相等待,直到到达某个公 ...
随机推荐
- 理解WebSocket心跳及重连机制(五)
理解WebSocket心跳及重连机制 在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件.这样会有:服务器会继续向客户端发送多余的 ...
- Redis 安装部署
1. 官网(https://redis.io/download)下载稳定版安装包 3.0.7或3.2或4.1; 2. 复制到部署服务器 /opt/redis4,解压 tar zxvf redis-4. ...
- 【LeetCode105】Construct Binary Tree from Preorder and Inorder Traversal★★
1.题目 2.思路 3.java代码 //测试 public class BuildTreeUsingInorderAndPreorder { public static void main(Stri ...
- Luogu3516 POI2011 Shift 构造
传送门 题意:给出一个长为$N$的排列,有两种操作:$A$:将最后一个数字放到第一个:$B$:将第三个数字放到第一个.一次性使用某种操作$k$次写作$kA$或$kB$,其中在$kA$中$k < ...
- Jquery UI 中的datepicker() ,获取日期后的回调函数onClose()
<head> //引入相关的css/js <link rel="stylesheet" href="//code.jquery.com/ui/1.10. ...
- 使用while和read命令读取文件内容
转:使用while和read命令读取文件内容 1.准备数据文件 $cat a.txt 200:2 300:3 400:4 500:5 2.用while循环从文件中读取数据 #!/bin/ksh whi ...
- VitualBox安装linux记录
下载镜像 CentOS 7镜像下载 阿里云站点:http://mirrors.aliyun.com/centos/7/isos/x86_64/ VirtualBox安装linux https://ww ...
- mybatis 思考
https://my.oschina.net/xianggao/blog/548579 https://my.oschina.net/xianggao/blog/548873 https://my.o ...
- php 中 opendir() readdir() scandir()
opendir(path,context)若成功,则该函数返回一个目录流,否则返回 false 以及一个 error.可以通过在函数名前加上 “@” 来隐藏 error 的输出. readdir() ...
- PAT甲题题解-1129. Recommendation System (25)-排序
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789819.html特别不喜欢那些随便转载别人的原创文章又不给 ...