多线程屏障CyclicBarrier

news2025/2/21 22:33:33

文章目录

  • 前言
  • 一、CyclicBarrier可以做什么?
  • 二、使用步骤
    • 1 单参数CyclicBarrier
    • 2 多参数 CyclicBarrier
    • 3 与CyclicBarrier类似的Exchanger
  • 总结


前言

多线程中的CyclicBarrier,同样也是juc包下的一个工具类;


一、CyclicBarrier可以做什么?

CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞;
意思就是:

  • 当我创建CyclicBarrier 的时候,入参就是屏障拦截线程的个数;
  • 当没有达到这个屏障拦截个数的时候,那么所有线程均被阻塞
  • 每个线程调用 CyclicBarrier 的 await(); 算是告诉 CyclicBarrier 到达了屏障

二、使用步骤

1 单参数CyclicBarrier

例如如下代码:

public class CyclicBarrierTest{

    /**
     * int 入参   其参数表示屏障拦截的线程数量,
     * 每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞
     * 只有线程的阻塞数量(到达屏障的数量) 与int 入参相当的时候,线程才会进入就绪状态,开始执行
     */
    static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);

    @SneakyThrows
    public static void main(String[] args) {


        new Thread(() -> {
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (BrokenBarrierException e) {
                throw new RuntimeException(e);
            }
            System.out.println("我是子线程");
        }).start();

        cyclicBarrier.await();
        System.out.println("我是主线程");

    }
}
  1. 其中创建CyclicBarrier 的时候入参为2
  2. 那么只有当有2 个线程调用了 CyclicBarrier 的 await()方法的时候,才会真正执行,否则一直被阻塞;
  3. 当 static CyclicBarrier cyclicBarrier = new CyclicBarrier(3); 那么执行这个方法,会一直阻塞,因为没有第三个线程调用 await() 方法;

执行结果
当改为3 之后

一直不结束
说明两个线程均被阻塞,正在等待第三个线程到达屏障,才会继续执行;

2 多参数 CyclicBarrier

例如如下代码:

public class CyclicBarrierPriority {

    static CyclicBarrier cyclicBarrier = new CyclicBarrier(2,() -> System.out.println("我先执行"));

    @SneakyThrows
    public static void main(String[] args) {

        new Thread(() -> {
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (BrokenBarrierException e) {
                throw new RuntimeException(e);
            }
            System.out.println("1");
        }).start();

        cyclicBarrier.await();
        System.out.println("2");

    }
}
  1. 第一个参数 与第一种相同,都是等待达到屏障的线程目标数量
  2. 第二个参数是 一个线程,它是一个最优先执行的线程; 当符合屏障数量之后,先执行第二个参数 也就是这个线程;

第二个参数线程优先执行
当入参中的第一个参数改为 3
那么这个线程永远不会执行,与之前类似,因为不会有第三个线程达到屏障,所以一直阻塞所有线程;

3 与CyclicBarrier类似的Exchanger

感觉应用场景不多,所以不单独写一片了,就在此处补充下; Exchanger与线程屏障功能类似,不通的是,它不是通过计数的形式,而是通过是否得到交换信息而实现的;

代码如下:

public class 线程交换信息 {


    @SneakyThrows
    public static void main(String[] args) {

        Exchanger<String> stringExchanger = new Exchanger<>();

        Thread thread = new Thread(() -> {
            System.out.println(Thread.currentThread().getName());
            try {
                System.out.println(Thread.currentThread().getName() + "我接受到了消息: " + stringExchanger.exchange("你好"));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        thread.setName("第一个");
        thread.start();

        Thread.sleep(2000);
        Thread thread1 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName());
            try {
                System.out.println(Thread.currentThread().getName() + "我接受到了消息: " + stringExchanger.exchange("hello"));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        thread1.setName("第二个");
        thread1.start();

    }
}

当第二个线程不运行的时候,第一个线程就会一直阻塞
直到有第二个线程与它进行信息交换后,两个线程才会继续运行
如果两个线程有一个没有执行exchange()方法,则会一直等待,如果担心有特殊情况发生,避免一直等待,可以使用exchange(V x,longtimeout,TimeUnit unit)设置最大等待时长;


总结

CyclicBarrier可以用于多线程计算数据,最后合并计算结果的场景; 与这篇文章类似:
多线程处理有序集合

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/587197.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#,码海拾贝(28)——求解“对称正定方程组”的“平方根法”之C#源代码,《C#数值计算算法编程》源代码升级改进版

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 求解线性方程组的类 LEquations /// 原作 周长发 /// 改编 深度混淆 /// </summary> public static partial class LEquations { /// <summary> /…

【译】Google Guava 的 Table 接口介绍

原文&#xff1a;https://www.baeldung.com/guava-table 1. 概述 在本教程中&#xff0c;我们将展示如何使用 Google Guava 的 Table 接口及其多个实现。 Guava 的 Table 是一种集合&#xff0c;表示包含行、列和相关单元格值的表结构&#xff0c;行和列充当有序的键对。 2…

React Native开发速记

文章目录 引子React Native适用场景React基础JSX 组件的定义基础APIFlex弹性布局例子: Flex布局实现多行多列 常用UI组件几个核心钩子函数useState用法useEffect典型用法 和原生模块交互调用原生模块方法 调试其它工具UI框架参考资源 引子 软件开发&#xff0c;移动优先&#…

webAJAX概述.

1.1什么是AJAX. Ajax即AsynchronousJavascript And XML&#xff1a;异步数据回调。 使用Ajax技术网页应用能够快速地将更新呈现在用户界面上&#xff0c;不需要重载&#xff08;刷新&#xff09;整个页面【只刷新局部】&#xff0c;这使得程序能够更快地回应用户的操作。、 1…

使用Node. js输出到命令行

目录 1、使用控制台模块的基本输出 2、清除控制台 3、计数元素 4、复位计数 5、打印堆栈跟踪 6、计算花费的时间 7、stdout和stderr 8、为输出着色 9、创建进度条 1、使用控制台模块的基本输出 Node.js提供了一个console模块&#xff0c;它提供了大量非常有用的与命令…

Qt Quick系列(4)—定位元素

&#x1f680;作者&#xff1a;CAccept &#x1f382;专栏&#xff1a;Qt Quick 文章目录 前言相对布局代码示例示例一示例二示例三示例四示例五示例六 简单"布局器"ColumnRowGridFlow 结语 前言 在Qt Quick中&#xff0c;可以使用以下方式来定位元素&#xff1a;…

需要建立强大的网络响应框架

由于头条新闻充斥着网络攻击&#xff0c;因此企业制定网络响应框架变得前所未有的重要。当今的网络安全形势继续快速发展&#xff0c;黑客行动主义、民族国家支持的网络攻击、勒索软件和其他攻击策略变得更加危险、复杂&#xff0c;组织的防御成本也越来越高。随着企业进行数字…

华为OD机试真题B卷 Java 实现【名字的漂亮度】,附详细解题思路

一、题目描述 给出一个字符串&#xff0c;该字符串仅由小写字母组成&#xff0c;定义这个字符串的“漂亮度”是其所有字母“漂亮度”的总和。 每个字母都有一个“漂亮度”&#xff0c;范围在1到26之间。没有任何两个不同字母拥有相同的“漂亮度”。字母忽略大小写。 给出多个…

Ex-ChatGPT本地部署+Azure OpenAI接口配置+docker部署服务

Ex-ChatGPT项目分为 Ex-ChatGPT 和 WebChatGPTEnhance 两部分&#xff0c;Ex-ChatGPT启动后是个web服务&#xff0c;通过访问ip端口体验&#xff1b; WebChatGPTEnhance可编译生成一个浏览器插件&#xff0c;Chrome或者Microsoft edge浏览器可以安装该插件&#xff0c;点击该插…

Golang中文件目录操作的实现

目录 文件 文件目录 文件目录操作 读取文件 一、方法一 (file.Read()) 二、方法二 (bufio读取文件) 三、方法三 (ioutil 读取方法) 写入文件 一、方法一 二、方法二 三、方法三 (ioutil写入文件) 复制文件 一、方法一 二、方法二 文件 Golang中&#xff0c;文件是…

python异常处理速通

一.异常处理认识 1.基础认识 开发人员在编写程序时&#xff0c;难免会遇到错误&#xff0c;有的是编写人员疏忽造成的语法错误&#xff0c;有的是程序内部隐含逻辑问题造成的数据错误&#xff0c;还有的是程序运行时与系统的规则冲突造成的系统错误&#xff0c;等等。总的来说…

什么是肖特基二极管

普通二极管是由N型半导体和P型半导体接触制成&#xff0c;交界面形成PN结。 肖特基二极管是由N型半导体和金属接触制成&#xff0c;交界面形成肖特基结。 肖特基结的形成主要是因为N型半导体中的电子更容易逸出进入到金属&#xff0c;从而在接触面N型半导体失去电子形成正离子区…

python:绘制GAM非线性回归散点图和拟合曲线

作者&#xff1a;CSDN _养乐多_ 本文将介绍使用python语言绘制广义线性模型&#xff08;Generalized Additive Model&#xff0c;GAM&#xff09;非线性回归散点图和拟合曲线。并记录了计算RMSE、ubRMSE、R2、Bias的代码。 文章目录 一、GAM非线性回归详解二、代码三、计算RM…

docker 镜像/容器的打包、导出、导入

目录 一、将变动过的容器打包生成新的镜像 二、对镜像进行导出导入 1、将镜像导出为一个镜像img文件 2、将img镜像文件导入&#xff0c;复制出一个完全一样镜像 三、对容器进行导入导出 1、将容器导出为一个镜像tar文件 2、将镜像tar文件导入&#xff0c;生成一个新镜像…

Linux本地搭建GitLab服务器 - 内网穿透远程访问

文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar内网穿透5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 转载自cpolar极点云文章&#xff1a;Linux搭建GitLab私有仓库&#xff0c;并内网穿透实…

vite构建的项目如何修改element Plus的主题样式

安装element plus 安装icon pnpm install element-plus pnpm install element-plus/icons-vue main.ts配置 icon的使用https://element-plus.gitee.io/zh-CN/component/icon.html#%E7%BB%93%E5%90%88-el-icon-%E4%BD%BF%E7%94%A8 import { createApp } from vue import ./sty…

【工具】vscode的常用插件之git插件

&#x1f41a;作者简介&#xff1a;花神庙码农&#xff08;专注于Linux、WLAN、TCP/IP、Python等技术方向&#xff09;&#x1f433;博客主页&#xff1a;花神庙码农 &#xff0c;地址&#xff1a;https://blog.csdn.net/qxhgd&#x1f310;系列专栏&#xff1a;善假于物&#…

计算机视觉cv模型最新进展速看:

华为诺亚实验室等研究者提出动态分辨率网络 DRNet 深度卷积神经网络通畅采用精细的设计&#xff0c;有着大量的可学习参数&#xff0c;在视觉任务上实现很高精 确度要求。为了降低将网络部署在移动端成本较高的问题&#xff0c;近来发掘在预定义架构上的冗余 已经取得了巨大的…

Midjourney AI绘画中文教程详解(完整版)模型、命令、参数与各种高级用法

我有一种预感&#xff0c;您一下子看不完这篇内容&#xff0c;您得【收藏】一下&#xff0c;以便下次接着看~~ Midjourney AI绘画中文教程&#xff0c;Midjourney是一款2022年3月面世的AI绘画工具&#xff0c;创始人是David Holz。 只要输入想到的文字&#xff0c;就能通过人…

数据库sqlserver-----触发器的插入,更新和删除

在学习触发器之前&#xff0c;先弄清DDL,DML,DQL,DCL的区别: http://t.csdn.cn/Le3wA 触发器就是当执行某个事件的时候触发另一个事件的执行&#xff0c;根据事件的触发时间可分为 before和after Before与After区别&#xff1a;before&#xff1a;(insert、update)可以对new…