Java多线程:CountDownLatch、CyclicBarrier 和 Semaphore
场景描述:
CountDownLatch
流程图
如上图所示,当7个线程都完成latch.countDown调用后,最下面那条线程会从latch.await返回,继续执行后面的代码
函数列表
- CountDownLatch(int count) :构造一个用给定计数初始化的 CountDownLatch。
- void await():使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。
- boolean await(long timeout, TimeUnit unit) 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。
- void countDown() 递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
实现原理
实例
我们来看一个具体的例子。假设我们使用一台多核的机器对一组数据进行排序,那么我们可以把这组数据分到不同线程中进行排序,然后合并;可以利用线程池来管理多线程;可以将CountDownLatch用作各个分组数据都排好序的通知。下面是代码片段:
先看主线程
int count = ;
final CountDownLatch latch = new CountDownLatch(count);
int[] datas = new int[];
int step = datas.length / count;
for (int i=; i < count; i++) {
int start = i * step;
int end = (i+) * step;
if (i == count - ) end = datas.length;
threadpool.execute(new MyRunnable(latch, datas, start, end));
}
latch.await();
//合并数据
我们再看一下具体任务的代码,即MyRunnable的run方法的实现:
public void run() {
//数据排序
latch.countDown();
}
CyclicBarrier
流程图
|
CountDownLatch
|
CyclicBarrier
|
适用场景
|
主线程等待其他工作线程结束
|
多个线程相互等待,直到所有线程都达到一个障碍点Barrier
|
主要方法
|
CountDownLatch(int count) 主线程调用:初始化计数
await() 主线程调用 : 阻塞,直到等待计数为0时解除阻塞
countDown() 工作线程调用 : 计数减1
|
CyclicBarrier(int parties , Runnnable barrierAction) : 初始化参与者数量和障碍点执行Action,action可选,由主线程初始化
await() : 由工作线程调用,每被调用一次,计数便会减少1,并阻塞住当前线程 , 直到所有线程都达到障碍点
|
等待结束
|
各线程之间不再相互影响, 可以继续做自己的事情, 不再执行下一个工作目标。
|
在障碍点到达后, 允许所有线程继续执行,到达下一个目标后,可以恢复使用CyclicBarrier, barrier 在释放等待线程后可以重用
|
异常
|
|
如果其中一个线程由于中断、错误、或者超时导致永久离开障碍点,其他线程也将抛出异常。
|
实例
int count = ;
final CyclicBarrier barrier = new CyclicBarrier(count + );
int[] datas = new int[];
int step = datas.length / count;
for (int i=; i < count; i++) {
int start = i * step;
int end = (i+) * step;
if (i == count - ) end = datas.length;
threadpool.execute(new MyRunnable(barrier, datas, start, end));
}
barrier.await();
//合并数据
可以看到CyclicBarrier对象传入的参数值比CountDownLatch大1,原因是构造CountDownLatch的参数是调用countDown的数量,而CyclicBarrier的数量是await的数量
public void run() {
//数据排序
try {
barrier.await();
}catch (...)
}
Semaphore
public Semaphore(int permits) { //参数permits表示许可数目,即同时可以允许多少线程进行访问
sync = new NonfairSync(permits);
}
public Semaphore(int permits, boolean fair) { //这个多了一个参数fair表示是否是公平的,即等待时间越久的越先获取许可
sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
}
实例
semaphore.acquire();
try {
//调用远程通信的方法
}
finally {
semaphore.release();
}
参考资料:
Java多线程:CountDownLatch、CyclicBarrier 和 Semaphore的更多相关文章
- 转:java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例
java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例 1.CountDownLatch:一个同步工具类,它允许一个或多个线程一 ...
- CountDownLatch CyclicBarrier和 Semaphore
CountDownLatch CyclicBarrier和 Semaphore 原理 基于AQS实现. 让需要的暂时阻塞的线程,进入一个死循环里面,得到某个条件后再退出循环,以此实现阻塞当前线程的效果 ...
- java 多线程 day15 CyclicBarrier 路障
import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.ut ...
- Java多线程-CountDownLatch、CyclicBarrier、Semaphore
上次简单了解了多线程中锁的类型,今天要简单了解下多线程并发控制的一些工具类了. 1. 概念说明: CountDownLatch:相当于一个待执行线程计数器,当计数减为零时表示所有待执行线程都已执行完毕 ...
- CountDownLatch, CyclicBarrier and Semaphore
Reference: [1] http://shazsterblog.blogspot.co.uk/2011/12/comparison-of-countdownlatch.html CountDow ...
- Java多线程系列——信号量:Semaphore
简介 信号量为多线程协作提供了更为强大的控制方法.也可以说,信号量是对锁的扩展.无论是内部锁 synchronized 还是重入锁 ReentrantLock,一次都只允许一个线程访问一个资源,而信号 ...
- java多线程 -- CountDownLatch 闭锁
CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown ...
- Java并发--CountDownLatch CyclicBarrier ReentrantLock
CountDownLatch CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行.CountDownLatch使用一个数字count初始化,使 ...
- Java多线程-新特征-信号量Semaphore
简介信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确.合理的使用公共资源. 概念Semaphore分为单值和多值两种,前者只能 ...
- java多线程-CountDownLatch
简介 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待.用给定的计数 初始化 CountDownLatch.由于调用了 countDown() 方法,所以在当前计数 ...
随机推荐
- 2006 ACM 求奇数的和
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2006 注意 sum=1,写在while 不然每次结果会累积 #include <stdio.h> ...
- Django——支付宝支付功能
前期准备 首先我们需要获得支付宝提供的权限与接口,在蚂蚁开放平台进行相关申请:https://openhome.alipay.com/platform/appDaily.htm?tab=info 申请 ...
- js数组去除重复
1. let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4]; let result = arr.sort().reduce((init, current)=>{ if(in ...
- Jmeter5 实现多机集群压测(局域网组成多机集群)
想要模拟高并发用户访问的场景,用Jmeter5实现的话,单靠一台PC机,资源是不够的,包括单机的内存.使用端口数量等,所以最好是通过多台PC机组成几个集群来对服务器进行压测. 本文目录: 1.软硬件配 ...
- BZOJ2130 : 魔塔
考虑从$0$到$n$枚举$A$的通关楼层. 设$f[i]$表示$B$通关$i$层时$C$最多能得到多少金币,因为金币数非负,所以也可以看作最多通关多少层. 当$A$的通关楼层往上多$1$的时候,这把钥 ...
- C#数组,ArrayList,List
一.数组声明方式 1,声明一个未经初始化的数组引用,以后可以把这引用初使化为一个数组实例 int[] int_array; int_array = new int[2]; 注:数组的引用必须以相同或相 ...
- Android探索之旅 | AIDL原理和实例讲解
轉載自http://www.jianshu.com/p/ef86f682a8f9 -- 作者 谢恩铭 转载请注明出处 前言 为使应用程序之间能够彼此通信,Android提供了IPC (Inter Pr ...
- MySql 数据库安装、环境变量配置 以及 本地连接
一.准备 MySql 的安装包,这里我从网上下载的是 mysql-installer-community-5.6.21.1.msi,如下图: 二.,双击 mysql-installer-com ...
- Could not load file or assembly 'System.Web.Mvc, Version=5.2.3.0...
一.在Mvc 发布时出现如下错误: Could not load file or assembly 'System.Web.Mvc, Version=5.2.3.0... 出现错误的原因是 Mvc版本 ...
- linux go环境安装和基本项目结构
最近项目中要用到Go语言,所以简单总结一下安装和配置,Go这个语言本身就限定了很多规范,比如项目设置,编程风格等,开发中就不需要再因为各种规范问题纠结了,直接用官方规定的能避免很多坑,下面直接切正题, ...