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() 方法,所以在当前计数 ...
随机推荐
- Codeforces.1096E.The Top Scorer(组合)
题目链接 感觉这题很裸啊,除了看着恶心点也没什么了,怎么过的人那么少.. \(Description\) 给定\(n,r,s\),表示有\(n\)个人,设每个人的得分是非负整数\(a_i\),已知第一 ...
- HDU.4694.Important Sisters(支配树)
HDU \(Description\) 给定一张简单有向图,起点为\(n\).对每个点求其支配点的编号和. \(n\leq 50000\). \(Solution\) 支配树. 还是有点小懵逼. 不管 ...
- Axis2部署后服务器端出现异常信息
客户端可以正常调用Web Service,但服务端控制台报出如下异常:2013-09-05 09:49:12,965:[http-8080-2] at org.apache.axis2.dataret ...
- 2107 ACM 水题
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2107 题意:比较大小,即使简单还是没有一次过,粗心的我,终于放假了,虽然我平时课还是有点多,但是希望自己能 ...
- 第一本docker书,,持续更新中
1.查看应用是否在docker中部署成功 需要确认curl已安装 whereis curl sudo apt-get -y install curl curl localhost:8081 如果成 ...
- IntelliJ IDEA classpath包含哪些文件夹以及如何把文件(夹)添加到classpath下
在IDEA中,标为蓝色的文件夹被认定为包含在classpath中,例如上图中的resources.src文件夹.把文件位置以"classpath:applicationContext.xml ...
- Drying [POJ3104] [二分答案]
背景 每件衣服都有一定单位水分,在不适用烘干器的情况下,每件衣服每分钟自然流失1个单位水分,但如果使用了烘干机则每分钟流失K个单位水分,但是遗憾是只有1台烘干机,每台烘干机同时只能烘干1件衣服,请问要 ...
- Python高级有关的题目
1,copy模块 from copy import deepcopy dic = {} list = [] for i in range(10): dic["num"] = i i ...
- GMA Round 1 逃亡
传送门 逃亡 你在森林中,遇到了一只老虎.此时此刻,老虎在(0,0)的位置,你在(2,1)的位置. 你开始沿着一条林间小路逃亡,移动向量是$(\frac{\sqrt{6}}{2},\frac{\sqr ...
- JSP(5)—Session的创建以及简单使用
页面: 1.案例 <body> <!-- 把书的信息以Cookie方式传回给浏览器,删除一个Cookie 1.确定要被删除的Cookie是以ATGUIGU_BOOK_开头的cooki ...