CyclicBarrier源码浅析
来源:互联网 发布:坐标数据库 编辑:程序博客网 时间:2024/06/05 21:11
CyclicBarrier内部实现很简单,利用ReentrantLock 和 Condition控制并发,
初始化的时候创建一个 计数器,每线程调用await方法的时候 计数器减1,再判断计数器是否等于0,
等于0的话,就唤醒所有 await的线程,不等于0的话,就调用condition的await方法等待
public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction;}
为什么这里会区分parties 和count参数呢,因为CyclicBarrier支持重置,是一种可循环的,基本上parties变量初始化后
就不会变了, 每次调用await都是改变count的值
public int await() throws InterruptedException, BrokenBarrierException { try { return dowait(false, 0L); } catch (TimeoutException toe) { throw new Error(toe); // cannot happen }}
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; //每次调用await count都会减一 if (index == 0) { //如果已经为0了,就会先调用构造函数中传入Runnable类执行(没传就不会调用) boolean ranAction = false; try { final Runnable command = barrierCommand; if (command != null) command.run(); ranAction = true; nextGeneration(); //唤醒所有等待的线程,把count重置为parties,创建新的Generation类 return 0; } finally { if (!ranAction) breakBarrier(); } } //如果index不为0的话,就会在这里被阻塞 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(); } } private void nextGeneration() { // 唤醒所有trip.await()的线程 trip.signalAll(); // set up next generation count = parties; generation = new Generation();}
获取正在等待中的 线程数量
public int getNumberWaiting() { final ReentrantLock lock = this.lock; lock.lock(); try { return parties - count; } finally { lock.unlock(); } }
重置CyclicBarrier类
public void reset() { final ReentrantLock lock = this.lock; lock.lock(); try { breakBarrier(); // break the current generation nextGeneration(); // start a new generation } finally { lock.unlock(); } }
阅读全文
0 0
- CyclicBarrier源码浅析
- CyclicBarrier源码
- Chapter 9 浅析CyclicBarrier类
- 深度解析CyclicBarrier源码
- CyclicBarrier 源码阅读
- 源码分析-CyclicBarrier
- CyclicBarrier源码分析
- CountDownLatch & CyclicBarrier源码实现解析
- Java 并发 --- CyclicBarrier源码分析
- Java多线程 - 浅析CyclicBarrier的用法
- cyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- 正则表达式基本语法
- mac 下执行脚本文件--亲测可行
- 如何读取STL文件?
- 【剑指offer】二叉搜索树的后序遍历序列
- Unity_脚本的认识_003
- CyclicBarrier源码浅析
- 《Effective Java中文版 第2版》(Joshua Bloch)pdf
- mysql存储过程while循环搭配if elseif选择条件
- 思维导图,带你走进“腹黑”政治家司马懿的一生
- sqlplus格式调整
- Oracle触发器案例
- 更新动态分区表
- centos7下安装mysql步骤
- [003]一步一步学懂spring