源码分析--CyclicBarrier

optee系统启动流程 BL2 - Trusted Boot Firmware,一般为Trusted Bootloader, 也称第一个启动镜像。BL31 - EL3 Runtime Firmware,负责双系统切换,运行在secure monitor 或ATF中。BL33 - Non-Trusted Firmware,一般为uboot、linux kernel。BL32 - Secure-EL1 Payload, 一般为TEE OS Image。BL1 - Trusted ROM,一般为BootRom。 阅读详情

概述

CyclicBarrier 是并发包中的一个工具类,它的典型应用场景为:几个线程执行完任务后,执行另一个线程(回调函数,可选),然后继续下一轮,如此往复。它与CountDownLatch很类似,但又不同,CountDownLatch需要调用countDown()方法触发事件,而CyclicBarrier不需要。

方法

在这里插入图片描述
使用样例:

public class CyclicBarrierTest {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);

        for (int i = 0; i < 3; i++) {
            new Thread(()->{
                System.out.println("before");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println("after");
            }).start();
        }
    }
}    

使用一个CyclicBarrier使得三个线程保持同步,当三个线程同时到达cyclicBarrier.await();处大家再一起往下运行。

源码分析

构造器:

    this(parties, null);
}

// 有回调函数
public CyclicBarrier(int parties, Runnable barrierAction) {
    if (parties <= 0) throw new IllegalArgumentException();
    this.parties = parties;
    this.count = parties;
    this.barrierCommand = barrierAction;
}

CyclicBarrier 有两个构造器,其中后者可以传入一个回调函数(barrierAction),parties 表示调用 await 的线程数。

成员变量

// 重入锁
private final ReentrantLock lock = new ReentrantLock();
// 条件锁,名称为trip,绊倒的意思,可能是指线程来了先绊倒,等达到一定数量了再唤醒
private final Condition trip = lock.newCondition();
// 需要等待的线程数量
private final int parties;
// 当唤醒的时候执行的命令
private final Runnable barrierCommand;
// 代
private Generation generation = new Generation();
// 当前这一代还需要等待的线程数
private int count;

内部类

private static class Generation {
    boolean broken = false;
}

常用方法:

// 阻塞式等待
public int await() throws InterruptedException, BrokenBarrierException {
    try {
        return dowait(false, 0L);
    } catch (TimeoutException toe) {
        throw new Error(toe); // cannot happen
    }
}

// 有超时的等待
public int await(long timeout, TimeUnit unit)
    throws InterruptedException,
           BrokenBarrierException,
           TimeoutException {
    return dowait(true, unit.toNanos(timeout));
}

可以看到两个 await 方法都是调用 dowait 方法来实现的(该方法也是 CyclicBarrier 的核心方法),如下:

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();
        }

        // count 减 1
        int index = --count;
        if (index == 0) {  // tripped
            // count 减到 0 时触发的操作
            boolean ranAction = false;
            try {
                // 传入的回调函数
                final Runnable command = barrierCommand;
                if (command != null)
                    // 若传了回调函数,则执行回调函数
                    // PS: 由此可知,回调函数由最后一个执行结束的线程执行
                    command.run();
                ranAction = true;
                // 进入下一代(下一轮操作)
                nextGeneration();
                return 0;
            } finally {
                if (!ranAction)
                    breakBarrier();
            }
        }

        // loop until tripped, broken, interrupted, or timed out
        for (;;) {
            try {
                // count 不为 0 时,当前线程进入等待状态
                if (!timed)
                    trip.await();
                else if (nanos > 0L)
                    nanos = trip.awaitNanos(nanos);
            } catch (InterruptedException ie) {
                if (g == generation && ! g.broken) {
                    breakBarrier();
                    throw ie;
                } else {
                    // We're about to finish waiting even if we had not
                    // been interrupted, so this interrupt is deemed to
                    // "belong" to subsequent execution.
                    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();
    }
}

nextGeneration 和 breakBarrier:

// 进入下一轮
private void nextGeneration() {
    // signal completion of last generation
    trip.signalAll();
    // set up next generation
    count = parties;
    generation = new Generation();
}

// 破坏屏障
private void breakBarrier() {
    generation.broken = true;
    count = parties;
    trip.signalAll();
}

dowait()方法里的整个逻辑分成两部分:

(1)最后一个线程走上面的逻辑,当count减为0的时候,打破栅栏,它调用nextGeneration()方法通知条件队列中的等待线程转移到AQS的队列中等待被唤醒,并进入下一代。

(2)非最后一个线程走下面的for循环逻辑,这些线程会阻塞在condition的await()方法处,它们会加入到条件队列中,等待被通知,当它们唤醒的时候已经更新换“代”了,这时候返回。

小结

(1)CyclicBarrier会使一组线程阻塞在await()处,当最后一个线程到达时唤醒(只是从条件队列转移到AQS队列中)前面的线程大家再继续往下走;
(2)CyclicBarrier不是直接使用AQS实现的一个同步器;
(3)CyclicBarrier基于ReentrantLock及其Condition实现整个同步逻辑;

vue3+vite - 解决报错error while updating dependencies:Error:EACCES:permission denied,mkdir ‘x‘(系统权限问题) vue3,vite,报错,nuxt,权限,苹果mac系统,windows系统,vue3报错,vite报错,node,详细解决方法,教程,[vite] error while updating dependencies: Error:EACCES:permission denied,mkdir 'x',更新依赖项时发生[vite]错误:错误:EACCES:权限被拒绝,mkdir,苹果mac系统加了sudo还是不行报错,运行报错,启动项目,run dev,创建项目,初始化,依旧不行怎么办,保权限没有问题,换了n 阅读详情

相关推荐

【论文复现】HiDDeN:Hiding Data With Deep Networks

(标签)是 float 类型,但代码中传入的是 long 类型(整数标签)。函数参数解析方式变化,导致无法正确保存生成的图像结果。这是因为新版torchvision的。使用预训练模型进行隐写和提取测试。HiDDeN支持多种噪声层组合。打印变量的类型,分别是。

qq_69146676的博客 971

CyclicBarrier源码分析

一、简介 在理解CyclicBarrier之前,最好先熟悉一下CountDownLatch的工作原理,这两个工具类都能达到线程等待的效果,但它们的侧重点有所不同,CountDownLatch只能使用一次,当它的计数器为0时会去唤醒所有同步队列中等待的线程,之后就不可用了。而CyclicBarrier的计数器可以被重置,达到重复使用的效果,所以它也就更适用于复杂的业务场景,比如如果计算发生错误时,可以通过重置计算器,让线程重复执行一次 CyclicBarrier:回环栅栏(循环屏障),通过它可以实现让一组线程

sermonlizhi的博客 653

【unity】Google 登录和Google支付接入unity

google 支付 google 登录

云渊寒烬 8495

深入理解 CyclicBarrier【源码分析】

CyclicBarrier 字面意思是环栅栏,是 JUC 下的一个并发工具,跟 CountDownLatch 很相似,都可以使线程先等待然后再执行,但是它的功能比 CountDownLatch 更加复杂和强大, CountDownLatch 是一个或者多个线程等待另外一批线程执行完毕后,在接着执行,而 CyclicBarrier 是等待一批线程到达某个状态之后再同时开始执行,回环的意思是当所有的线程被释放后,CyclicBarrier 可以被重启,也就是可以重复使用。如有错误的地方欢迎指出纠正。

weixin_42118323的博客 705

Windows版MySQL8.4.2LTS解压直用(下载免安装-绿色-项目打包直接使用-含卸载)

安装前运行微软常用运行库全集(也可能称为依赖)关于MySQL8中相关参数配置,可通过。选择8.5.2LTS长期服务版。选中密码,右键会直接复制。

xzzteach的博客 1439

医疗器械软件测试输出内容(1)

*单元测试(Unit Testing):**单元测试是软件测试的最底层,用于验证软件中最小的可测试单元——函数、方法或模块。系统测试是在集成测试之后进行的,它对整个系统进行测试,验证系统在不同部分集成在一起后是否满足需求和规格。: 集成测试是在单元测试之后进行的,它关注不同单元之间的交互和集成。对于不同安全级别的软件(IEC 62304 A类、B类、C类),在体系上要求输出的文件内容有所区别。**说明:**将集成测试和软件系统测试合并为一项单一的计划和一组活动是可接收的。

ct745363083的博客 1867

【并发编程】CyclicBarrier 源码分析

等待/通知模型、屏障等。

yhl_jxy的博客 1314

飞塔防火墙和paloalto防火墙构建ipsec

一、配置fortigate防火墙1.防火墙配置上网功能1.1配置fortigate的wan1接口IP为100.100.100.2/24VLAN交换internal,IP地址为192.168.156.99/24。开启DHCP分配IP地址范围为192.168.156.110-192.168.156.2101.2配置访问互联网的缺省路由1.3配置访问互联网的安全策略2.配置与Paloalto防火墙的IPSECVPN。

weixin_44675999的博客 3738

10、深入理解AQS之循环栅栏CyclicBarrier

CyclicBarrier基于 ReentrantLock + ConditionObject实现,CyclicBarrier的构造函数中必须指定parties,同时对象generation,内部持有布尔型属性表示当前CyclicBarrier执行过程中是否有超时、异常、中断的情况。parties是初始待执行线程数,在构造函数中会将parties赋给计数值count,每当一个线程执行await(),count就会减1。

sproutBoy的博客 1133

Wazuh部署记录

Wazuh是一个免费的开源安全平台,统一了XDR和SIEM功能。它可以保护内部部署、虚拟化、容器化和基于云的环境中的工作负载。Wazuh帮助组织和个人保护其数据资产免受安全威胁。它被全球数千个组织广泛使用,从小型企业到大型企业。443:仪表盘界面访问端口1515:探针连接服务器端口1514:探针回传信息端口以上3个端口必须打开防火墙。

墨痕诉清风的博客 1559

零基础DSP实战TMS320F28035:第九节,ADC比较器&EPWM

ADC比较器框图如下所示:-电压-----------------------------输出-电压A>电压B------------------ 1-电压A

sinat_30943509的博客 2535

CyclicBarrier的源码分析

与CountDownLatch、Semaphore直接基于AQS实现不同,CyclicBarrier 是基于 ReentrantLock + ConditionObject 实现的,间接基于AQS实现的。

Zhuxiaoyu_91的博客 725

OpenMVS :用 colmap制作自己的数据集 重建(用colmap计算位姿,将位姿转为MVS需要的格式)

数据集制作主要是在windows进行,比较方便。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 3325

并发工具CyclicBarrier源码分析及应用

今天是猿灯塔“365天原创计划”第3天。 今天呢!灯塔君跟大家讲: 并发工具CyclicBarrier源码分析及应用 一.CyclicBarrier简介 1.简介 CyclicBarrier是一个同步的辅助类,允许一组线程相互之间等待,达到一个共同点,再继续执行。 CyclicBarrier(循环屏障) 直译为可循环使用(Cyclic)的屏障(Barrier)。它可以让一组线程到 达一个屏障(同...

猿灯塔的博客 329

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

CyclicBarrier应用&源码分析

从名字上来看CyclicBarrier,就是代表循环屏障Barrier屏障:让一个或多个线程达到一个屏障点,会被阻塞。屏障点会有一个数值,当达到一个线程阻塞在屏障点时,就会对屏障点的数值进行-1操作,当屏障点数值减为0时,屏障就会打开,唤醒所有阻塞在屏障点的线程。在释放屏障点之后,可以先执行一个任务,再让所有阻塞被唤醒的线程继续之后后续任务。Cyclic循环:所有线程被释放后,屏障点的数值可以再次被重置。CyclicBarrier一般被称为栅栏。

优快云博客 927

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

cyclicbarrier java_Java并发系列[8]----CyclicBarrier源码分析

现实生活中我们经常会遇到这样的情景,在进行某个活动前需要等待人全部都齐了才开始。例如吃饭时要等全家人都上座了才动筷子,旅游时要等全部人都到齐了才出发,比赛时要等运动员都上场后才开始。在JUC包中为我们提供Java并发系列[8]----CyclicBarrier源码分析了一个同步工具类能够很好的模拟这类场景,它就是CyclicBarrier类。利用CyclicBarrier类可以实现一组线程相互等待...

weixin_42516967的博客 169

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

《Java源码分析》:CyclicBarrier(part two)

《Java源码分析》:CyclicBarrier(part two)在上篇博文中http://blog.youkuaiyun.com/u010412719/article/details/52156588,我们看了关于CyclicBarrier应用的一些例子,也得出的使用CyclicBarrier时的相关结论。回顾下我们在上篇博文中了解了关于CyclicBarrier的相关知识点如下:1、CyclicBarri

wojiushimogui的博客 1008

11. Java JUC源码分析系列笔记-CyclicBarrier

if(index ==0) {// 最后一个到达booleanranActionfalse;tryfinalRunnablecommand//最后一个到达的线程先执行Runnableif(command!nulltrue;//唤醒所有线程继续往下执行(46行)并且换代//返回,不往下执行死循环return0;finallyifranAction)死循环直到超时或者信号量都用完或者中断for;

weixin_40827985的博客 71

CyclicBarrier 源码分析

使用 public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(3); System.out.println("hahaha"); for (int i=0; i<3; i++) { new Worker(cyclicBarrier).start(); } System.out.

xuwenjingrenca的博客 218
上一篇: 源码分析--CountDownLatch
下一篇: 源码分析--Semaphore
CodersCoder
博客等级 码龄10年 90粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值