CountDownLatch、CyclicBarrier、Semaphore共同之处与区别以及各自使用场景
区别
- CountDownLatch 使一个线程A或是组线程A等待其它线程执行完毕后,一个线程A或是组线程A才继续执行。CyclicBarrier:一组线程使用await()指定barrier,所有线程都到达各自的barrier后,再同时执行各自barrier下面的代码。Semaphore:是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源
- CountDownLatch是减计数方式,计数==0时释放所有等待的线程;CyclicBarrier是加计数方式,计数达到构造方法中参数指定的值时释放所有等待的线程。Semaphore,每次semaphore.acquire(),获取一个资源,每次semaphore.acquire(n),获取n个资源,当达到semaphore 指定资源数量时就不能再访问线程处于阻塞,必须等其它线程释放资源,semaphore.relase()每次资源一个资源,semaphore.relase(n)每次资源n个资源。
- CountDownLatch当计数到0时,计数无法被重置;CyclicBarrier计数达到指定值时,计数置为0重新开始。
- CountDownLatch每次调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响;CyclicBarrier只有一个await()方法,调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞。
- CountDownLatch、CyclikBarrier、Semaphore 都有一个int类型参数的构造方法。CountDownLatch、CyclikBarrier这个值作为计数用,达到该次数即释放等待的线程,而Semaphore 中所有acquire获取到的资源达到这个数,会使得其它线程阻塞。
共同
- CountDownLatch与CyclikBarrier两者的共同点是都具有await()方法,并且执行此方法会引起线程的阻塞,达到某种条件才能继续执行(这种条件也是两者的不同)。Semaphore,acquire方获取的资源达到最大数量时,线程再次acquire获取资源时,也会使线程处于阻塞状态。CountDownLatch与CyclikBarrier两者的共同点是都具有await()方法,并且执行此方法会引起线程的阻塞,达到某种条件才能继续执行(这种条件也是两者的不同)。Semaphore,acquire方获取的资源达到最大数量时,线程再次acquire获取资源时,也会使线程处于阻塞状态。CountDownLatch、CyclikBarrier、Semaphore 都有一个int类型参数的构造方法。
- CountDownLatch、CyclikBarrier、Semaphore 都有一个int类型参数的构造方法。
CountDownLatch、CyclicBarrier和Semaphore使用场景
CountDownLatch
由于CountDownLatch有个countDown()方法并且countDown()不会引起阻塞,所以CountDownLatch可以应用于主线程等待所有子线程结束后再继续执行的情况。具体使用方式为new一个构造参数为subThread数目的CountDownLatch,启动所有子线程后主线程await(),在每个子线程的最后执行countDown(),这样当所有子线程执行完后计数减为0,主线程释放等待继续执行。比如赛跑,每个运动员看做一个子线程,裁判就是主线程,裁判发令(设置一个值为1的计数器,发令之前所有子线程await等待命令,裁判员发令让计数置为0,所有子线程同时开跑)所有运动员开跑后,需要等待所有人跑完再统计成绩(设置一个值为运动员数目的计数器,所有运动员开跑后裁判await被阻塞,每个运动员跑完的时候countDown()一下,所有运动员跑完计数达到0,裁判释放阻塞开始计分)。
public class CountDownLatchCase {
public static void main(String args[]){
//主线程为裁判,子线程为运动员
final CountDownLatch operatorNum=new CountDownLatch(6);
for(int i=0;i<6;i++){
new Thread(new Runnable() {
@Override
public void run() {
Long s=System.currentTimeMillis();
Random random=new Random();
try {
Thread.sleep(random.nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
Long time=System.currentTimeMillis()-s;
System.out.println(String.format(”运动员%s跑完,花了%s”, Thread.currentThread().getName(),time));
//一个运动员跑完了
operatorNum.countDown();
}
}).start();
}
try {
operatorNum.await();
System.out.println(String.format(”所有运行员都跑完了,裁判%s可宣布结果啦!”, Thread.currentThread().getName()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
CyclicBarrier
/**
* 各省数据独立,分库存偖。为了提高计算性能,统计时采用每个省开一个线程先计算单省结果,最后汇总。
*
* @author guangbo email:weigbo@163.com
*
*/
public class Total { // private ConcurrentHashMap result = new ConcurrentHashMap(); public static void main(String[] args) {
TotalService totalService = new TotalServiceImpl();
CyclicBarrier barrier = new CyclicBarrier(5,
new TotalTask(totalService)); // 实际系统是查出所有省编码code的列表,然后循环,每个code生成一个线程。
new BillTask(new BillServiceImpl(), barrier, “北京”).start();
new BillTask(new BillServiceImpl(), barrier, “上海”).start();
new BillTask(new BillServiceImpl(), barrier, “广西”).start();
new BillTask(new BillServiceImpl(), barrier, “四川”).start();
new BillTask(new BillServiceImpl(), barrier, “黑龙江”).start(); }
} /**
* 主任务:汇总任务
*/
class TotalTask implements Runnable {
private TotalService totalService; TotalTask(TotalService totalService) {
this.totalService = totalService;
} public void run() {
// 读取内存中各省的数据汇总,过程略。
totalService.count();
System.out.println(”=======================================”);
System.out.println(”开始全国汇总”);
}
} /**
* 子任务:计费任务
*/
class BillTask extends Thread {
// 计费服务
private BillService billService;
private CyclicBarrier barrier;
// 代码,按省代码分类,各省数据库独立。
private String code; BillTask(BillService billService, CyclicBarrier barrier, String code) {
this.billService = billService;
this.barrier = barrier;
this.code = code;
} public void run() {
System.out.println(”开始计算–” + code + “省–数据!”);
billService.bill(code);
// 把bill方法结果存入内存,如ConcurrentHashMap,vector等,代码略
System.out.println(code + ”省已经计算完成,并通知汇总Service!”);
try {
// 通知barrier已经完成
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
} }
Semaphore
CountDownLatch、CyclicBarrier、Semaphore共同之处与区别以及各自使用场景的更多相关文章
- 并发包下常见的同步工具类详解(CountDownLatch,CyclicBarrier,Semaphore)
目录 1. 前言 2. 闭锁CountDownLatch 2.1 CountDownLatch功能简介 2.2 使用CountDownLatch 2.3 CountDownLatch原理浅析 3.循环 ...
- CountDownLatch/CyclicBarrier/Semaphore 使用过吗?
CountDownLatch/CyclicBarrier/Semaphore 使用过吗?下面详细介绍用法: 一,(等待多线程完成的)CountDownLatch 背景; countDownLatch ...
- Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo
Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...
- 并发包下常见的同步工具类(CountDownLatch,CyclicBarrier,Semaphore)
在实际开发中,碰上CPU密集且执行时间非常耗时的任务,通常我们会选择将该任务进行分割,以多线程方式同时执行若干个子任务,等这些子任务都执行完后再将所得的结果进行合并.这正是著名的map-reduce思 ...
- 高并发第十单:J.U.C AQS(AbstractQueuedSynchronizer) 组件:CountDownLatch. CyclicBarrier .Semaphore
这里有一篇介绍AQS的文章 非常好: Java并发之AQS详解 AQS全名:AbstractQueuedSynchronizer,是并发容器J.U.C(java.lang.concurrent)下lo ...
- Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger
在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...
- CountDownLatch CyclicBarrier Semaphore 比较
document CountDownLatch A synchronization aid that allows one or more threads to wait until a set of ...
- 多线程中 CountDownLatch CyclicBarrier Semaphore的使用
CountDownLatch 调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行.也可以传入时间,表示时间到之后,count还没有为0的时候,就会继续执行. package ...
- 等待某(N)个线程执行完再执行某个线程的几种方法(Thread.join(),CountDownLatch,CyclicBarrier,Semaphore)
1.main线程中先调用threadA.join() ,再调用threadB.join()实现A->B->main线程的执行顺序 调用threadA.join()时,main线程会挂起,等 ...
随机推荐
- 阿里云服务器,Sql Server 本地连接服务器端问题记录
1.如果你是阿里云服务器,配置参数都整好了并且排除了防火墙问题(关闭了防火墙),依然没有连接上,那就先考虑这个问题 问题:阿里云服务器的SQLServer不允许远程连接 原因:因为除了服务器上的防火墙 ...
- MyDAL - .QueryListAsync() 使用
索引: 目录索引 一.API 列表 .QueryListAsync() .QueryListAsync<M>() 如: .QueryListAsync<AgentInventoryR ...
- Windows中通过命令行启动打开Service 管理工具
经常需要打开Services 管理工具操控Service 的启动,停止. 通过控制面板 --> 管理工具 -->Service 太慢. 学到一个快捷方式. windows + R 启动 ...
- asp.net FromBody接收不到参数的解决方法
今天改一个前端框架(angularjs,不兼容ie内核,需要修改),后台框架是已经写好了的,不用修改. 接口接收参数如下: [HttpPost] public async Task<Schedu ...
- Web前端教程-HTML及标签的使用
目录 1. HTML简介 1.1. HTML文档基本结构 2. 标签 2.1. 标签语法 1.2. 标签的属性和值 1.3. 常见的标签 1. 基础标签 2. 格式标签 3. 表单标签 4. 框架标签 ...
- 【Linux基础】Linux命令date 日期时间
1.显示到纳秒 date +%F.%H:%M:%S.%N --:38.740127086 date +%Y-%m-%d.%H:%M:%S.%N2019-04-25.00:28:24.060756673 ...
- jupyter notebook修改默认路径和浏览器
1.jupyter notebook --generate-config 2.修改jupyter_notebook_config.py配置文件 3.修改默认路径: c.NotebookApp.note ...
- Pycharm 常用快捷键
常用快捷键 快捷键 功能 Ctrl + Q 快速查看文档 Ctrl + F1 显示错误描述或警告信息 Ctrl + / 行注释(可选中多行) Ctrl + Alt + L 代码格式化 Ctrl + A ...
- LA3971 组装电脑
思路:二分,就是在不超过b的预算下,使得品质的最小值最大化.关键还是判断函数吧. 假设答案为x,判断函数,就是每一个种类的配件的品质最基本的品质要大于x,然后找出最小的值.这样的配件品质之和的价格要小 ...
- 【原创】那些年用过的Redis集群架构(含面试解析)
引言 今天是2019年2月12号,也就是大年初八,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上Redis是如何部署的,导致面试失败! 人间惨 ...