- 浏览: 341154 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (212)
- spring (21)
- design pattern(java) (12)
- linux-shell (28)
- java-thread (20)
- java-collection (6)
- java-reflect (9)
- mysql (11)
- java-io (7)
- java-util&lang&io (3)
- algorithm (3)
- interview (2)
- tools-eclipse (2)
- tools-maven (1)
- web-script (1)
- java组建 (13)
- 博客收藏 (1)
- 架构设计与实践 (10)
- active-mq (6)
- java-jvm&性能&原理 (27)
- tomcat (2)
- flume (1)
- serialization (2)
- git (1)
- cache&redis (8)
- guava (1)
- zookeeper (3)
- socket&tcp&udp&http (6)
- test (1)
最新评论
-
bbls:
有用有用有用
java-jvm-jstack-(监视器和锁的概念) -
王新春:
小侠有点帅哦 写道此流怎么关闭新春这个实现 可以不关闭的,哈哈 ...
源码剖析之java.io.ByteArrayOutputStream -
小侠有点帅哦:
此流怎么关闭新春
源码剖析之java.io.ByteArrayOutputStream -
cumt168:
写的很好为什么初始化参数,年轻代-Xmn10M def new ...
jvm之内存申请过程分析 -
ronin47:
应该是跟共享域名思路差不多,根据cookie的key作判断
跨域:一种通过服务端解决跨域的实现
CyclicBarrier:jdk current 包提供了一个让多个线程在某个点到达之前都互相等待的工具类,并且可以多次循环使用,故曰:循环障碍器。
使用场景:它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在屏障点运行一次,(注意:实际上是在最后一个线程中执行的!!!)若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。 【···引用jdk中文翻译】
实现依赖:
1、lock 可重入锁 ReentrantLock
2、Condition 条件谓词。
实现思路:就是设置一个计数,每当有线程达到时,计数count-1,Condition.await 进入阻塞, 当count =0,那么可以 signalAll ,让所有线程得以唤醒。 唤醒后立马重置!
核心代码分析如下:
以上是我个人的分析和理解,如果逻辑偏差,请指出,非常感谢!
使用场景:它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在屏障点运行一次,(注意:实际上是在最后一个线程中执行的!!!)若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。 【···引用jdk中文翻译】
实现依赖:
1、lock 可重入锁 ReentrantLock
2、Condition 条件谓词。
实现思路:就是设置一个计数,每当有线程达到时,计数count-1,Condition.await 进入阻塞, 当count =0,那么可以 signalAll ,让所有线程得以唤醒。 唤醒后立马重置!
核心代码分析如下:
public class CyclicBarrier { /** 进入障碍前必须获取的锁 */ private final ReentrantLock lock = new ReentrantLock(); /** 用来表示阻塞的条件 */ private final Condition trip = lock.newCondition(); /** 障碍释放前需要wait的线程数量*/ private final int parties; /* 障碍突破后 要执行的命令 */ private final Runnable barrierCommand; /** 英文翻译:代。 其实更准确的含义是 轮,相当于一次集合到释放为为一轮,一轮一轮的进行*/ private Generation generation = new Generation(); /** 重置后count = parties;表示:目前等待还需要的线程的数量才能结束当前轮,进入下一轮 */ private int count; /** 跳出障碍后,唤醒所有等待中的线程, 重置障碍器状态 (获取锁后才可以调用) 注意:generation 被被改变,那么其他线程会优先被 signalAll 。(分析dowait 请结合此处的逻辑)*/ private void nextGeneration() { // signal completion of last generation trip.signalAll(); // set up next generation count = parties; generation = new Generation(); } /* 打破障碍,设置当前线程的generation ,并唤醒所有等待中的线程 注意:只被这个方法调用才有机会 设置generation.broken = true ,这个方法调用后 其他等待的线程是会被trip.signalAll()的 ,如果没有进入下一轮,后来的线程是直接抛出异常的。(分析dowait 请结合此处的逻辑) */ private void breakBarrier() { generation.broken = true; count = parties; trip.signalAll(); } /** parties - 在启动 barrier 前必须调用 await() 的线程数 barrierAction - 在启动 barrier 时执行的命令;如果不执行任何操作,则该参数为 null */ public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } /** 在所有参与者中的最后一个线程到达之前,所有已经在此 barrier 上调用 await 方法都将进入阻塞状态! 如果当前线程不是将到达的最后一个线程,出于调度目的,将阻塞它,且在发生以下情况之一前,该线程将一直处于休眠状态: 1、最后一个线程到达;(很容易理解吧:nextGeneration 和 breakBarrier 方法 无论调用哪一个都会signalAll 的) 2、其他某个线程中断当前线程;(处于阻塞于此障碍器)另一个等待线程;(当前状态 wait,那么其他线程中断当前线程,wait 会抛出异常(如果还不明白,请仔细理解Condition.wait 的含义)) 3、其他某个线程中断(其他线程被中断了,那么其他线程会调用breakBarrier 方法,然后notifyALl) 4、其他某个线程在等待 barrier 时超时;(效果同上:会调用breakBarrier) 5、其他某个线程在此 barrier 上调用 reset()。 (同3) 如果当前线程: 1、在进入此方法时已经设置了该线程的中断状态; 2、在等待时被中断 则抛出 InterruptedException,并且清除当前线程的已中断状态。 */ public int await() throws InterruptedException, BrokenBarrierException { try { return dowait(false, 0L); } catch (TimeoutException toe) { throw new Error(toe); // cannot happen; } } /** 线程wait的真实实现 timed:是否是有时间限制 nanos:wait的纳秒数 */ 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) //如果当前状态已经break ,如果breakBarrier 方法的调用没有和nextGeneration 同时出现,那么后继的线程会在这里抛出异常!!! throw new BrokenBarrierException(); if (Thread.interrupted()) { //如果当前线程已经中断,那么break 障碍器,释放已经在此等待的线程,并抛出异常。 如果此后还有线程跟进,那么会直接抛出异常,其实就是上面的这句:if(g.broken) !!! breakBarrier(); throw new InterruptedException(); } int index = --count; //随着当前线程的道理,如果index == 0 ,那么当前线程就是最后一个到达的线程,即:会引起障碍器打破 if (index == 0) { // tripped boolean ranAction = false; try { final Runnable command = barrierCommand; if (command != null) command.run(); //先执行障碍命令任务 ranAction = true; nextGeneration(); return 0; //正常返回 } finally { if (!ranAction) breakBarrier(); //最后无论如何,打破障碍器! 主要是针对:command.run 可以抛出异常的情况!!! } } // 循环直到 障碍逃出 打破 中断 或者超时! for (;;) { try { if (!timed) //如果不支持超时,那么直接在条件谓词处等待! trip.await(); else if (nanos > 0L) nanos = trip.awaitNanos(nanos); //如果是nanos >0,那么在trip上等待nanos时间!! } catch (InterruptedException ie) { //如果wait得到notify,那么肯定不会进入这块!!!只有当前线程被打断 才有机会。 if (g == generation && ! g.broken) { //只有其他线程打断当前线程 会进入这块 breakBarrier(); //如果发生异常,那么打破障碍器,并抛出异常!!! throw ie; } else { /*这个是个十分特殊的地方经过仔细的思考,我发现这块代码压根走不到!!! 进入此处,那么一定其他线程中断了当前线程,如果wait状态下没有被notifyAll唤醒,那么g == generation 必然成立,而generation.broken = true 时,可以肯定会被唤醒而不是中断当前线程。(这块理解起来确实比较别扭) private void nextGeneration() { // signal completion of last generation trip.signalAll(); // set up next generation count = parties; generation = new Generation(); //如果当前的generation 变了,那么会先被signalAll,不会进入这里 } */ Thread.currentThread().interrupt(); } } /**如果g已经被打破了,那么抛出异常 想想什么情况下g.broken 会为false 呢? */ if (g.broken) throw new BrokenBarrierException(); if (g != generation) //如果g != geneation ,那么可以认定:障碍器重置了,或者所有线程已经达到了!! return index; if (timed && nanos <= 0L) { //如果是支持超时,并且nanos<=0 ,那么打破障碍器,并抛出超时的异常 breakBarrier(); throw new TimeoutException(); } } } finally { lock.unlock(); //最后不要忘记解锁 } } /** 重置障碍器*/ public void reset() { final ReentrantLock lock = this.lock; lock.lock(); try { breakBarrier(); // break the current generation nextGeneration(); // start a new generation } finally { lock.unlock(); } } /** 返回当前在屏障处等待的参与者数目 */ public int getNumberWaiting() { final ReentrantLock lock = this.lock; lock.lock(); try { return parties - count; } finally { lock.unlock(); } } }
以上是我个人的分析和理解,如果逻辑偏差,请指出,非常感谢!
发表评论
-
Thread.isInterrupted 的理解
2017-05-24 21:01 1857interrupt方法用于中断线程。调用该方法的线程的状态 ... -
Condition&(wait,notify)
2017-05-22 10:58 561Condition.await和Object.wait ... -
AQS-预备-背景
2017-05-20 18:16 608AbstractQueuedSynchronizer: ... -
LockSupport
2017-05-19 22:15 590LockSupport类是Java6(JSR166-JUC ... -
Synchronized&AbstractQueuedSynchronizer[摘抄]
2017-05-19 21:29 514目前在Java中存在两种锁机制:synchronized和 ... -
CountDownLatch/CyclicBarrier
2017-05-19 20:59 978CountDownLatch: 功能:是一个同步工具类 ... -
Thread-wait/notify
2017-05-19 11:59 659java 线程通过对象的Wait和Notify进行同步,但 ... -
AQS-预备-FIFOMutex
2017-05-18 20:25 520通过AtomicBoolean 和队列 ... -
AQS-预备知识 CLH lock queue[摘抄]
2017-05-18 20:07 419经典! -
多个线程到达后才能执行某个任务,并且只能执行一次
2015-04-02 23:51 4016有一种场景:多个线程到达(比如合并多个线程返回的结果)后才能执 ... -
ThreadLocal 在web环境下使用的边界问题
2014-06-12 13:30 3524ThreadLocal 相关分析,请查看http://wang ... -
原码剖析之ThreadPoolExecutor进阶
2013-06-17 17:15 1755继续ThreadPoolExecutor 线程池的分析~~~~ ... -
原码剖析之ThreadPoolExecutor入门
2013-06-15 10:44 1438jdk 1.5 开始提供支持线 ... -
源码剖析之ThreadLocal
2013-06-08 12:57 3248背景:1、如果一个对象 ... -
Thread的join方法
2013-02-25 23:44 1610Thread类中的join方法的语义: void java. ... -
lock 锁class类对象和实例对象
2013-02-25 23:18 2200java thread 线程中 的synchronized关键 ... -
lock实现运行时死锁检测
2013-02-24 23:02 1563java的多线程机制非常强 ... -
异常与锁的释放(synchronized )
2013-02-16 23:28 5442synchronized 获取的锁,在方法抛出异常的时候会自动 ... -
异常与锁的释放(lock)
2013-02-16 22:57 2599获取lock锁后发生异常后,线程退出,lock锁不释放 p ...
相关推荐
Java并发包源码分析(JDK1.8):囊括了java.util.concurrent包中大部分类的源码分析,其中涉及automic包,locks包...对每个类的核心源码进行详细分析,笔记详细,由浅入深,层层深入,带您剖析并发编程原理
内容包括 01-并发编程之深入理解JMM&并发三大特性(一)-fox 02-并发编程之深入理解JMM&并发三...11-深入理解AQS之CyclicBarrier&ReentrantReadWriteLock详解-fox 12-深入理解AQS之ReentrantReadWriteLock详解-fox ...
本资源摘要信息涵盖了 Java 后端开发的多个方面,包括 JPA 防踩坑姿势、Servlet 3 异步原理与实践、Tomcat 源码剖析、Java 并发编程、Java 线程池、AbstractQueuedSynchronizer、Tomcat 系列、Netty 系列、Kafka ...
本文将围绕“guava源码src”这一主题,深入剖析Guava的核心组件和设计理念,帮助开发者提升对Java编程的理解和应用能力。 1. **Guava集合框架**:Guava提供了许多强大的集合类,如Multiset、Multimap、...
4-10 深入剖析ReentrantReadWriteLock之读锁源码实现.mp4 4-11 深入剖析ReentrantReadWriteLock之写锁源码实现.mp4 4-12 锁降级详解.mp4 4-13 StampedLock原理及使用.mp4 5-1 wait、notify、notifyAll.mp4 5-2 ...
4-10 深入剖析ReentrantReadWriteLock之读锁源码实现.mp4 4-11 深入剖析ReentrantReadWriteLock之写锁源码实现.mp4 4-12 锁降级详解.mp4 4-13 StampedLock原理及使用.mp4 5-1 wait、notify、notifyAll.mp4 5-2 ...
4-10 深入剖析ReentrantReadWriteLock之读锁源码实现.mp4 4-11 深入剖析ReentrantReadWriteLock之写锁源码实现.mp4 4-12 锁降级详解.mp4 4-13 StampedLock原理及使用.mp4 5-1 wait、notify、notifyAll.mp4 5-2 ...
4-10 深入剖析ReentrantReadWriteLock之读锁源码实现.mp4 4-11 深入剖析ReentrantReadWriteLock之写锁源码实现.mp4 4-12 锁降级详解.mp4 4-13 StampedLock原理及使用.mp4 5-1 wait、notify、notifyAll.mp4 5-2 ...
4-10 深入剖析ReentrantReadWriteLock之读锁源码实现.mp4 4-11 深入剖析ReentrantReadWriteLock之写锁源码实现.mp4 4-12 锁降级详解.mp4 4-13 StampedLock原理及使用.mp4 5-1 wait、notify、notifyAll.mp4 5-2 ...
"juc源码视频教程"将引导你逐层剖析这些组件的内部工作原理,让你在实践中更好地运用并发编程技术。 本视频教程可能包含如下内容: 1. JUC组件的设计理念和使用场景。 2. 深入分析ExecutorService的工作流程和...
线程之间通信之join应用与实现原理剖析.mp4 ThreadLocal 使用及实现原理.mp4 并发工具类CountDownLatch详解.mp4 并发工具类CyclicBarrier 详解.mp4 并发工具类Semaphore详解.mp4 并发工具类Exchanger详解.mp4 ...
《深入解析Java并发编程:Unsafe类与LockSupport类源码剖析》 在Java并发编程领域,Unsafe类和LockSupport类是两个重要的底层工具类,它们提供了低级别的内存操作和线程控制,使得开发者能够实现高效的并发算法和...
在Java开发中,JDK的性能是影响应用程序效率的关键因素之一。JDK(Java Development Kit)是Java编程语言的核心组成部分,它包含了一个Java虚拟机(JVM)、编译器、类库以及开发者工具,是运行Java程序的基础。本文...
本文将针对"jdk:jdk源码分析"这一主题,对JDK的核心组件进行详细的剖析。 首先,我们来看看JDK的主要组成部分。JDK包含了JRE(Java Runtime Environment),这是执行Java程序的必备环境;JVM(Java Virtual Machine...
在这一部分,作者深入剖析了Java并发包中的核心组件,如ExecutorService、Semaphore、CountDownLatch、CyclicBarrier等,以及并发工具类如BlockingQueue和Future。通过对这些组件的实现原理进行解析,读者可以理解...
第35节线程之间通信之join应用与实现原理剖析00:10:17分钟 | 第36节ThreadLocal 使用及实现原理00:17:41分钟 | 第37节并发工具类CountDownLatch详解00:22:04分钟 | 第38节并发工具类CyclicBarrier 详解00:11:52...
第35节线程之间通信之join应用与实现原理剖析00:10:17分钟 | 第36节ThreadLocal 使用及实现原理00:17:41分钟 | 第37节并发工具类CountDownLatch详解00:22:04分钟 | 第38节并发工具类CyclicBarrier 详解00:11:52...
第35节线程之间通信之join应用与实现原理剖析00:10:17分钟 | 第36节ThreadLocal 使用及实现原理00:17:41分钟 | 第37节并发工具类CountDownLatch详解00:22:04分钟 | 第38节并发工具类CyclicBarrier 详解00:11:52...
第35节线程之间通信之join应用与实现原理剖析00:10:17分钟 | 第36节ThreadLocal 使用及实现原理00:17:41分钟 | 第37节并发工具类CountDownLatch详解00:22:04分钟 | 第38节并发工具类CyclicBarrier 详解00:11:52...