博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java并发系列—工具类:CyclicBarrier
阅读量:6606 次
发布时间:2019-06-24

本文共 2858 字,大约阅读时间需要 9 分钟。

CyclicBarrier的字面意思是循环屏障。允许一组线程达到一个屏障(或者同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被拦截的线程才会继续运行。

使用实例

public class CyclicBarrierDemo {    public static void main(String[] args) {        CyclicBarrier cyclicBarrier = new CyclicBarrier(2);        new Thread(new Action(cyclicBarrier)).start();        new Thread(new Action(cyclicBarrier)).start();    }   static class Action implements Runnable{        private CyclicBarrier cyclicBarrier;        public Action(CyclicBarrier cyclicBarrier){            this.cyclicBarrier = cyclicBarrier;        }        @Override        public void run() {            System.out.println(Thread.currentThread()+" get ready");            try {                cyclicBarrier.await();            } catch (InterruptedException | BrokenBarrierException e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread()+" work done");        }    }}复制代码

实现原理

通过查看源码可知await()方法由dowait()方法完成的,源码如下:

private int dowait(boolean timed, long nanos)    throws InterruptedException, BrokenBarrierException,           TimeoutException {    // 1、获取锁并加锁    final ReentrantLock lock = this.lock;    lock.lock();    try {        // 2、获取代表屏障使用的generation实例        final Generation g = generation;        if (g.broken)            throw new BrokenBarrierException();        if (Thread.interrupted()) {            breakBarrier();            throw new InterruptedException();        }        // 3、被拦截的线程数的副本值 - 1        int index = --count;        if (index == 0) {  // tripped            boolean ranAction = false;            try {                final Runnable command = barrierCommand;                if (command != null)                    command.run();                ranAction = true;                // 5、唤醒被拦截的线程和初始化下一次屏障使用                nextGeneration();                return 0;            } finally {                if (!ranAction)                    breakBarrier();            }        }        // loop until tripped, broken, interrupted, or timed out        // 4、当前线程进入自旋过程,释放锁等待被唤醒        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();    }}复制代码

dowait方法的执行流程如下:

欢迎留言补充,共同交流。个人微信公众号求关注

转载地址:http://wzbso.baihongyu.com/

你可能感兴趣的文章
2-11
查看>>
Appium IOS
查看>>
POJ1961 Period [KMP应用]
查看>>
CSS hack
查看>>
IT项目管理工具探讨之_项目群管理
查看>>
如何在 Android 手机上安装 Ubuntu 13.04
查看>>
HDU 6073 - Matching In Multiplication | 2017 Multi-University Training Contest 4
查看>>
编程面试过程中常见的10大算法(转)
查看>>
centos6.5 安装nginx
查看>>
生成若干个不重复的随机数数组
查看>>
topcoder srm 465 div1
查看>>
C语言 scanf()和gets()函数的区别
查看>>
如何检测域名是否被微信屏蔽 微信域名检测接口API是如何实现
查看>>
POJ1611-The Suspects
查看>>
ROS学习之ShadowRepository
查看>>
Spring 中 ApplicationContext 和 BeanFactory 的区别
查看>>
3.28Day09函数
查看>>
Linux Makefile 生成 *.d 依赖文件及 gcc -M -MF -MP 等相关选项说明【转】
查看>>
Linux下安装Python-3.3.2【转】
查看>>
STL杂记
查看>>