多线程屏障CyclicBarrier

文章目录

  • 前言
  • 一、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.mfbz.cn/a/26216.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一款开源的无线CMSIS DAP ARM芯片下载调试器详细说明

文章目录 概要1. 一般概念1.1 CMSIS—DAP的一般概念1.2 支持的芯片1.3 典型应用场景 2. 原理图与尺寸图2.1 Host端&#xff08;发送端&#xff09;原理图2.2 Target&#xff08;目标&#xff09;端原理图2.3 Host尺寸图2.4 Target尺寸图2.5 实物图 3. 使用方法3.1 连接方法3.1.…

4-5.配置信息和路由信息

一、配置信息 app.run()的参数 参数1&#xff1a;host&#xff0c;如果我们不指定&#xff0c;默认值是127.0.0.1。参数2&#xff1a;port&#xff0c;如果我们不指定&#xff0c;默认值是5000。参数3&#xff1a;debug&#xff0c;调试模式&#xff0c;如果不指定&#xff0…

电力系统直流潮流计算研究【IEEE9节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

皮卡丘反射型XSS

1.反射型xss(get) 进入反射型xss(get)的关卡&#xff0c;我们可以看到如下页面 先输入合法数据查看情况&#xff0c;例如输入“kobe” 再随便输入一个&#xff0c;比如我舍友的外号“xunlei”&#xff0c;“666”&#xff0c;嘿嘿嘿 F12查看源代码&#xff0c;发现你输入的数…

什么是SOME/IP?

SOME/IP 是"Scalable service-Oriented MiddlewarE over IP"的缩写&#xff0c;即可扩展的面向服务的IP中间件&#xff0c;由AUTOSAR发布。它是一种自动/嵌入式通信协议&#xff0c;它支持远程过程调用、事件通知和底层序列化/线格式。唯一有效的缩写是SOME/IP&#…

软件测试想要高薪资,不仅要卷还要学会跳槽

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。 这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作都没两年&#xff0c;跳槽到我们公司起薪20K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了…

正在破坏您的协程(Coroutines)的无声杀手(Silent Killer)

正在破坏您的协程的无声杀手 处理 Kotlin 中的取消异常的唯一安全方法是不重新抛出它们。 今天生产服务器再次停止响应流量。 上个星期&#xff0c;你刚重新启动它们并将其视为故障。但是你总觉得有些奇怪&#xff0c;因为日志中没有任何错误的痕迹&#xff0c;甚至没有警告。…

求图的最短路径长度的弗洛伊德(Floyd)算法

弗洛伊德算法的适用情况&#xff1a;弗洛伊德算法既可以用来求解有向网的最短路径长度&#xff0c;也可以用来求无向网的最短路径长度&#xff0c;但是对于图中出现负权环的情况&#xff0c;弗洛伊德无法的得到正确的答案 弗洛伊德的算法思想&#xff1a; 以此图为例讲解弗洛…

从git上拉取项目

目录 一、前期准备&#xff0c;获取git下载链接 二、idea下载 2.1.打开git下载界面 2.2.进入下载界面 2.3.下载前期配置 2.4.输入账号密码 2.5.下载完成后idea打开 2.6.下载完成后文件目录展示 三、命令行下载 3.1.打开所需要下载的项目路径 3.2.进入黑窗口 …

c#快速入门(下)

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析2 目录 &#x1f449;&#x1f3fb;Inline和lambda委托和lambda &#x1f449;&#x1f…

操作系统(2.8)--线程的实现

目录 线程的实现方式 1.内核支持线程(KST) 2.用户级线程(ULT) 3.组合方式 线程的实现 1.内核支持线程的实现 2.用户级线程的实现 线程的创建和终止 线程的实现方式 1.内核支持线程(KST) 内核支持线程&#xff0c;与进程相同&#xff0c;是在内核的支持下运行的&#x…

前端使用tailwindcss 快速实现主题切换方案

使用Tailwind CSS在黑暗模式下为你的网站设计样式。 现在&#xff0c;黑暗模式是许多操作系统的第一流功能&#xff0c;为你的网站设计一个黑暗版本以配合默认设计&#xff0c;变得越来越普遍。 为了使这一点尽可能简单&#xff0c;Tailwind包括一个暗色变体&#xff0c;让你…

JVM之类的初始化与类加载机制

类的初始化 clinit 初始化阶段就是执行类构造器方法clinit的过程。此方法不需定义&#xff0c;是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来。构造器方法中指令按语句在源文件中出现的顺序执行。clinit不同于类的构造器。(关联&#xff1a;…

连锁药店系统:如何提高效率和客户满意度?

连锁药店系统是一种用于提高效率和客户满意度的软件系统&#xff0c;它能够管理多个药店的日常营运。通过这种系统&#xff0c;药店可以更好地管理库存、员工、销售和客户信息等方面&#xff0c;从而提高整体的经营效率。 首先&#xff0c;连锁药店系统能够帮助药店管理库存。系…

算法刷题总结 (十一) 二叉树

算法总结11 二叉树 一、二叉树的概念1.1、什么是二叉树&#xff1f;1.2、二叉树的常见类型1.2.1、无数值&#xff08;1&#xff09;、满二叉树&#xff08;2&#xff09;、完全二叉树 1.2.2、有数值&#xff08;3&#xff09;、二叉搜索树&#xff08;4&#xff09;、平衡二叉搜…

数字孪生与物流园区:优化布局规划的关键

随着全球贸易的增长和物流行业的发展&#xff0c;物流园区作为重要的物流枢纽和供应链管理中心&#xff0c;扮演着至关重要的角色。而数字孪生技术的出现为物流园区的运营和管理带来了革命性的变化。数字孪生技术是一种将实体物体与其数字化模型相结合的创新技术&#xff0c;通…

【UEFI】BIOS 阶段全局变量类型

BIOS的几个阶段需要不同阶段的数据传递&#xff0c;下面介绍4个全局变量。 1 固件存储介绍 本规范描述了应该如何在非易失性存储器中存储和访问文件。固件实现必须支持标准的PI固件卷和固件文件系统格式&#xff08;下文所述&#xff09;&#xff0c;但可能支持其他存储格式。…

什么是一致性哈希?一致性哈希是如何工作的?如何设计一致性哈希?

1.什么是一致性哈希&#xff1f;一致性哈希是如何工作的&#xff1f;如何设计一致性哈希&#xff1f;05-25 2.系统设计&#xff1a;从零用户扩展到百万用户05-28 收起 如果你有 n 个缓存服务器&#xff0c;一个常见的负载均衡方式是使用以下的哈希方法&#xff1a; 服务器索…

强连通分量-tarjan算法缩点

一. 什么是强连通分量&#xff1f; 强连通分量&#xff1a;在有向图G中&#xff0c;如果两个顶点u,v间&#xff08;u->v&#xff09;有一条从u到v的有向路径&#xff0c;同时还有一条从v到u的有向路径&#xff0c;则称两个顶点强连通(strongly connected)。如果有向图G的每…

NLP实战:调用Gensim库训练Word2Vec模型

目录 一、准备工作 1. 安装Gensim库 2. 对原始语料分词 二、训练Word2Vec模型 三、模型应用 1.计算词汇相似度 ​编辑 2. 找出不匹配的词汇 3. 计算词汇的词频 四、总结 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学…
最新文章