多线程条件通行工具——CyclicBarrier
CyclicBarrier的作用是,线程进入等待后,需要达到一定数量的等待线程后,再一次性开放通行。
- CyclicBarrier(int, Runnable)
构造方法,参数1为通行所需的线程数量,参数2为条件满足时的监听器。 - int await()/int await(long, TimeUnit)
线程进入等待,并返回一个进入等待时的倒计索引。 - int getParties()
通行所需的线程数量 - int getNumberWaiting()
当前线程数量 - boolean isBroken()
本批次是否已经终止 - reset()
释放本批次通行,并重新接收下一批线程进入。
源码分析:
/**
* @since 1.5
* @see CountDownLatch
*
* @author Doug Lea
*/
public class CyclicBarrier { public CyclicBarrier(int parties) {
this(parties, null);
} public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0)
throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
} private static class Generation {
boolean broken = false;
} private final ReentrantLock lock = new ReentrantLock();
private final Condition trip = lock.newCondition();
private final int parties;
private final Runnable barrierCommand;
private Generation generation = new Generation(); private int count; private void nextGeneration() {
// 通知本批次所有线程可通行
trip.signalAll();
// 重置计数器
count = parties;
// 重建批次对象,即不同批次使用不同对象
generation = new Generation();
} private void breakBarrier() {
// 标示本批次已终止
generation.broken = true;
// 重置计数器
count = parties;
// 通知本批次所有线程可通行
trip.signalAll();
} public int getParties() {
// 返回通行所需的线程数量
return parties;
} public int await() throws InterruptedException, BrokenBarrierException {
try {
return dowait(false, 0L);
} catch (TimeoutException toe) {
throw new Error(toe);
}
} public int await(long timeout, TimeUnit unit) throws InterruptedException,
BrokenBarrierException, TimeoutException {
return dowait(true, unit.toNanos(timeout));
} private int dowait(boolean timed, long nanos) throws InterruptedException,
BrokenBarrierException, TimeoutException {
final ReentrantLock lock = this.lock;
// 进入同步
lock.lock();
try {
final Generation g = generation; // 如果本批次已终止,则抛出异常
if (g.broken)
throw new BrokenBarrierException(); // 如果线程已终止,则终止本批次
if (Thread.interrupted()) {
breakBarrier();
throw new InterruptedException();
} // 更新计数器
int index = --count;
// 判断是否达到可释放的线程数量
if (index == 0) {
// 观察监听器是否正常运行结束
boolean ranAction = false;
try {
// 执行监听器
final Runnable command = barrierCommand;
if (command != null)
command.run();
// 标记正常运行
ranAction = true;
// 通知所有线程并重置
nextGeneration();
// 返回索引
return 0;
} finally {
// 如果监听器是运行时异常结束,则终止本批次
if (!ranAction)
breakBarrier();
}
} for (;;) {
// 进入等待或计时等待
try {
if (!timed)
trip.await();
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && !g.broken) {
breakBarrier();
throw ie;
} else {
Thread.currentThread().interrupt();
}
} if (g.broken)
throw new BrokenBarrierException(); // 如果已经换批,则返回索引退出
if (g != generation)
// 返回索引
return index; // 如果超时,则 止本批次
if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
// 退出同步
lock.unlock();
}
} public boolean isBroken() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 返回本批次是否已经终止
return generation.broken;
} finally {
lock.unlock();
}
} public void reset() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 终止本批次
breakBarrier();
// 开始下一批
nextGeneration();
} finally {
lock.unlock();
}
} public int getNumberWaiting() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 返回本批次等待中的线程数量
return parties - count;
} finally {
lock.unlock();
}
}
}
多线程条件通行工具——CyclicBarrier的更多相关文章
- 多线程条件通行工具——AbstractQueuedSynchronizer
本文原创,转载请注明出处! 参考文章: <"JUC锁"03之 公平锁(一)> <"JUC锁"03之 公平锁(二)> AbstractOw ...
- 多线程条件通行工具——CountDownLatch
CountDownLatch的作用是,线程进入等待后,需要计数器达到0才能通行. CountDownLatch(int)构造方法,指定初始计数. await()等待计数减至0. await(long, ...
- 多线程条件通行工具——Semaphore
Semaphore的作用是,限制线程通行的数量,如果线程进入时达到通行数量,便等待其它正在通行的线程释放. acquire()获取通行 release()释放通行 availablePermits() ...
- Java多线程_同步工具CyclicBarrier
CyclicBarrier概念:CyclicBarrier是多线程中的一个同步工具,它允许一组线程互相等待,直到到达某个公共屏障点.形象点儿说,CyclicBarrier就是一个屏障,要求这一组线程中 ...
- 并发工具CyclicBarrier源码分析及应用
本文首发于微信公众号[猿灯塔],转载引用请说明出处 今天呢!灯塔君跟大家讲: 并发工具CyclicBarrier源码分析及应用 一.CyclicBarrier简介 1.简介 CyclicBarri ...
- JAVA多线程提高十:同步工具CyclicBarrier与CountDownLatch
今天继续学习其它的同步工具:CyclicBarrier与CountDownLatch 一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公 ...
- JAVA多线程学习十三 - 同步工具CyclicBarrier与CountDownLatch
一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序 ...
- 并发工具CyclicBarrier
想想一下这样一个场景,有多个人需要过河,河上有一条船,船要等待满10个人才过河,过完河后每个人又各自行动. 这里的人相当于线程,注意这里,每个线程运行到一半的时候,它就要等待一个条件,即船满过河的条件 ...
- java多线程并发控制countDownLatch和cyclicBarrier的使用
java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程来执行,所有处理完成了之后才会返回给用 ...
随机推荐
- 前端开发中SEO的十二条总结
一. 合理使用title, description, keywords二. 合理使用h1 - h6, h1标签的权重很高, 注意使用频率三. 列表代码使用ul, 重要文字使用strong标签四. 图片 ...
- Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作
Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 1.实施前准备工作 1.1 服务器安装操 ...
- 学点HTTP知识
不学无术 又一次感觉到不学无术,被人一问Http知识尽然一点也没答上来,丢人丢到家了啊.平时也看许多的技术文章,为什么到了关键时刻就答不上来呢? 确实发现一个问题,光看是没有用的,需要实践.看别人说的 ...
- 分布式锁1 Java常用技术方案
前言: 由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解决这些问题.所以自己结合实际工作中的一些经验和网上看到的一些资 ...
- C++中的事件分发
本文意在展现一个C++实现的通用事件分发系统,能够灵活的处理各种事件.对于事件处理函数的注册,希望既能注册到普通函数,注册到事件处理类,也能注册到任意类的成员函数.这样在游戏客户端的逻辑处理中,可以非 ...
- C语言 · 阶乘计算 · 基础练习
问题描述 输入一个正整数n,输出n!的值. 其中n!=1*2*3*-*n. 算法描述 n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法.使用一个数组A来表示一个大整数a,A[0]表 ...
- 路由的Resolve机制(需要了解promise)
angular的resovle机制,实际上是应用了promise,在进入特定的路由之前给我们一个做预处理的机会 1.在进入这个路由之前先懒加载对应的 .js $stateProvider .state ...
- JAVA问题集锦Ⅰ
1.Java的日期添加: import java.util.Date ; date=new date();//取时间 Calendar calendar = new GregorianCalendar ...
- Android数据存储之Android 6.0运行时权限下文件存储的思考
前言: 在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以 ...
- Android性能优化之巧用软引用与弱引用优化内存使用
前言: 从事Android开发的同学都知道移动设备的内存使用是非常敏感的话题,今天我们来看下如何使用软引用与弱引用来优化内存使用.下面来理解几个概念. 1.StrongReference(强引用) 强 ...