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() 方法,所以在当前计数 ...
随机推荐
- Scrapy基础(十)———同步机制将Item中的数据写在Mysql
前面讲解到将Item中的所有字段都已经填写完成,那么接下来就是将他们存储到mysql数据库中,那就用到了pipeline项目管道了: 对项目管道的理解:做一个比喻,爬取好比是开采石油,Item装 ...
- 南方IT学校期末PCB结课项目考试(实操)说明书
南方IT学校期末结课项目考试(实操)说明书(一) 课程:<印制电路板设计技术>(二) 项目:笔记本电脑电源适配器的印制电路板设计(三) 背景说明:如今笔记本已经进入千家万户,作为给电脑充电 ...
- 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第5章编程练习2
#include <iostream>using namespace std;const int MAXSIZE=100;int main(){ int a[MAXSIZE]; int s ...
- ae:org.apache.shiro.authc.AuthenticationException: Authentication token of type [class org.apache.shiro.authc.UsernamePasswordToken] could not be authenticated by any configured realms. Please ensure
看问题是说要保证有一个realm正确,但是之前运行就一直成功,后来就不行了.有可能是:以为自己输入了正确的用户名和密码,结果是因为用户名前面添加了空格导致了这个错误发生. 实质问题是:你输入的用户名和 ...
- JS中原始类型Null和Undefined
Undefined类型只有一个值,即undefined.当声明的变量还未被初始化时,变量的默认值为undefined.Null类型也只有一个值,即null.null用来表示尚未存在的对象,常用来表示函 ...
- elment ui 图片上传遇到的一些问题
图片上传返回200,message显示请上传图片 注意上图中的name字段要和服务器接受的name相同,这里我们是imgfile,默认name不是这个,所以要在el-upload组件上设置name属性 ...
- db2 reorgchk
db2 reorgchk 命令是最重要的.也是经常被忽略的 DB2 调整命令之一. db2 reorgchk 命令被忽略是因为它不是一个一次性调整项.由于更新是在 DB2 数据库上执行的,因此关于表的 ...
- django session源码剖析
首先要明白,session和cookie,session是保存在服务器端,cookie存储在浏览器上,我们称为客户端,客户端向服务端发送请求时,会将cookie一起发送给服务端.服务端接收到请求后,会 ...
- JAVA自学笔记07
JAVA自学笔记07 1.构造方法 1) 例如:Student s = new Student();//构造方法 System.out.println(s);// Student@e5bbd6 2)功 ...
- [原创]Burp Suite web应用程序渗透测试神器
[原创]Burp Suite web应用程序渗透测试神器 一 Burp Suite介绍 Burp Suite是Web应用程序测试的最佳工具之一,其多种功能可以帮我们执行各种任务.请求的拦截和修改,扫描 ...