iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >Java中CyclicBarrier循环屏障怎么应用
  • 701
分享到

Java中CyclicBarrier循环屏障怎么应用

2023-06-30 15:06:15 701人浏览 独家记忆
摘要

这篇“Java中CyclicBarrier循环屏障怎么应用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java中Cycli

这篇“Java中CyclicBarrier循环屏障怎么应用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java中CyclicBarrier循环屏障怎么应用”文章吧。

一、简介

CyclicBarrier 字面意思回环栅栏(循环屏障),它可以实现让一组线程等待至某个状态(屏障点)之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。 

Java中CyclicBarrier循环屏障怎么应用

CyclicBarrier 作用是让一组线程相互等待,当达到一个共同点时,所有之前等待的线程再继续执行,且 CyclicBarrier 功能可重复使用。

二、CyclicBarrier的使用

构造方法:

 // parties表示屏障拦截的线程数量,每个线程调用 await 方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。 public CyclicBarrier(int parties) // 用于在线程到达屏障时,优先执行 barrierAction,方便处理更复杂的业务场景(该线程的执行时机是在到达屏障之后再执行)

重要方法:

//屏障 指定数量的线程全部调用await()方法时,这些线程不再阻塞// BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时public int await() throws InterruptedException, BrokenBarrierExceptionpublic int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException//循环  通过reset()方法可以进行重置

CyclicBarrier 应用场景

  • 利用 CyclicBarrier 可以用于多线程计算数据,最后合并计算结果的场景。

  • 利用 CyclicBarrier的计数器能够重置,屏障可以重复使用的特性,可以支持类似“人满发车”的场景

模拟合并计算场景

利用 CyclicBarrier 可以用于多线程计算数据,最后合并计算结果的场景。

public class CyclicBarrierTest2 {    //保存每个学生的平均成绩    private Conc urrentHashMap<String, Integer> map=new ConcurrentHashMap<String,Integer>();    private ExecutorService threadPool= Executors.newFixedThreadPool(3);    private CyclicBarrier cb=new CyclicBarrier(3,()->{        int result=0;        Set<String> set = map.keySet();        for(String s:set){            result+=map.get(s);        }        System.out.println("三人平均成绩为:"+(result/3)+"分");    });    public void count(){        for(int i=0;i<3;i++){            threadPool.execute(new Runnable(){                @Override                public void run() {                    //获取学生平均成绩                    int score=(int)(Math.random()*40+60);                    map.put(Thread.currentThread().getName(), score);                    System.out.println(Thread.currentThread().getName()                            +"同学的平均成绩为:"+score);                    try {                        //执行完运行await(),等待所有学生平均成绩都计算完毕                        cb.await();                    } catch (InterruptedException | BrokenBarrierException e) {                        e.printStackTrace();                    }                }            });        }    }    public static void main(String[] args) {        CyclicBarrierTest2 cb=new CyclicBarrierTest2();        cb.count();    }}

模拟“人满发车”的场景

利用CyclicBarrier的计数器能够重置,屏障可以重复使用的特性,可以支持类似“人满发车”的场景

public class CyclicBarrierTest3 {    public static void main(String[] args) {        AtomicInteger counter = new AtomicInteger();        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(                5, 5, 1000, TimeUnit.SECONDS,                new ArrayBlockingQueue<>(100),                (r) -> new Thread(r, counter.addAndGet(1) + " 号 "),                new ThreadPoolExecutor.AbortPolicy());        CyclicBarrier cyclicBarrier = new CyclicBarrier(5,                () -> System.out.println("裁判:比赛开始~~"));        for (int i = 0; i < 10; i++) {            threadPoolExecutor.submit(new Runner(cyclicBarrier));        }    }    static class Runner extends Thread{        private CyclicBarrier cyclicBarrier;        public Runner (CyclicBarrier cyclicBarrier) {            this.cyclicBarrier = cyclicBarrier;        }        @Override        public void run() {            try {                int sleepMills = ThreadLocalRandom.current().nextInt(1000);                Thread.sleep(sleepMills);                System.out.println(Thread.currentThread().getName() + " 选手已就位, 准备共用时: " + sleepMills + "ms" + cyclicBarrier.getNumberWaiting());                cyclicBarrier.await();            } catch (InterruptedException e) {                e.printStackTrace();            }catch(BrokenBarrierException e){                e.printStackTrace();            }        }    }}

输出结果:

3 号  选手已就位, 准备共用时: 78ms0
1 号  选手已就位, 准备共用时: 395ms1
5 号  选手已就位, 准备共用时: 733ms2
2 号  选手已就位, 准备共用时: 776ms3
4 号  选手已就位, 准备共用时: 807ms4
裁判:比赛开始~~
4 号  选手已就位, 准备共用时: 131ms0
3 号  选手已就位, 准备共用时: 256ms1
2 号  选手已就位, 准备共用时: 291ms2
1 号  选手已就位, 准备共用时: 588ms3
5 号  选手已就位, 准备共用时: 763ms4
裁判:比赛开始~~

三、CyclicBarrier 源码分析

CyclicBarrier 流程

主要是的流程:

  • 获取 如果 count != 0 就进入阻塞;

  • 进入阻塞之前,首先需要进入条件队列,然后释放锁,最后阻塞;

  • 如果 count != 0 会进行一个唤醒,将所有的条件队列中的节点转换为阻塞队列;

  • 被唤醒过后会进行锁的获取,如果锁获取失败,会进入 lock 的阻塞队列;

  • 如果锁获取成功,进行锁的释放,以及唤醒,同步队列中的线程。

下面是一个简单的流程图:

Java中CyclicBarrier循环屏障怎么应用

下面是具体的一些代码调用的流程:

Java中CyclicBarrier循环屏障怎么应用

几个常见的问题?

  • 一组线程在触发屏障之前互相等待,最后一个线程到达屏障后唤醒逻辑是如何实现的. 唤醒的过程是通过调用 java.util.concurrent.locks.Condition#signalAll唤醒条件队列上的所有节点。

  • 删栏循环使用是如何实现的? 实际上一个互斥锁 ReentrantLock 的条件队列和阻塞队列的转换。

  • 条件队列到同步队列的转换实现逻辑 ? 转换过程中,首先会先将条件队列中所有的阻塞线程唤醒,然后会去获取 lock 如果获取失败,就进入同步队列。

CyclicBarrier 与 CountDownLatch的区别

  • CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次

  • CyclicBarrier还提供getNumberWaiting(可以获得CyclicBarrier阻塞的线程数量)、isBroken(用来知道阻塞的线程是否被中断)等方法。

  • CountDownLatch会阻塞主线程,CyclicBarrier不会阻塞主线程,只会阻塞子线程。

  • CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同。CountDownLatch一般用于一个或多个线程,等待其他线程执行完任务后,再执行。CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行。

  • CyclicBarrier 还可以提供一个 barrierAction,合并多线程计算结果。

  • CyclicBarrier是通过ReentrantLock的"独占锁"和Conditon来实现一组线程的阻塞唤醒的,而CountDownLatch则是通过AQS的“共享锁”实现

以上就是关于“Java中CyclicBarrier循环屏障怎么应用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。

--结束END--

本文标题: Java中CyclicBarrier循环屏障怎么应用

本文链接: https://www.lsjlt.com/news/329831.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java中CyclicBarrier循环屏障怎么应用
    这篇“Java中CyclicBarrier循环屏障怎么应用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java中Cycli...
    99+
    2023-06-30
  • Java中CyclicBarrier 循环屏障
    目录一、简介二、CyclicBarrier的使用CyclicBarrier 应用场景模拟合并计算场景模拟“人满发车”的场景三、CyclicBarrier 源码...
    99+
    2024-04-02
  • Java CountDownLatch计数器与CyclicBarrier循环屏障怎么定义
    本文小编为大家详细介绍“Java CountDownLatch计数器与CyclicBarrier循环屏障怎么定义”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java CountDownLatch计数器与CyclicB...
    99+
    2023-07-05
  • JavaCountDownLatch计数器与CyclicBarrier循环屏障
    目录定义CountDownLatch 示例CyclicBarrier 示例定义 CountDownLatch: A synchronization aid that allows o...
    99+
    2023-05-14
    Java CyclicBarrier Java CountDownLatch
  • JUC循环屏障CyclicBarrier与CountDownLatch区别详解
    目录前言介绍和使用API介绍基本使用实现原理成员属性构造方法成员方法和CountDownLatch的区别相同点不同点总结前言 jdk中提供了许多的并发工具类,大家可能比较熟悉的有Co...
    99+
    2022-12-08
    JUC循环屏障 JUC CyclicBarrier CountDownLatch
  • AQS同步组件CyclicBarrier循环屏障用例剖析
    目录CyclicBarrier原理源码分析使用案例await()await(long timeout, TimeUnit unit)CyclicBarrier(int parties...
    99+
    2022-11-13
    AQS同步组件CyclicBarrier AQS CyclicBarrier循环屏障
  • Java并发编程回环屏障CyclicBarrier
    CyclicBarrier 前面介绍的CountDownLatch在解决多个线程同步方面相对于调用线程的join方法已经有了不少优化。但是CountDownLatch的计数器是一次性...
    99+
    2024-04-02
  • Java循环屏障中CyclicBarrier如何实现多线程分段等待执行完成
    Java循环屏障中CyclicBarrier如何实现多线程分段等待执行完成,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。前言工作中是否有这样的场景,多个线程任务...
    99+
    2023-06-25
  • Java并发编程回环屏障CyclicBarrier实例分析
    本文小编为大家详细介绍“Java并发编程回环屏障CyclicBarrier实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java并发编程回环屏障CyclicBarrier实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入...
    99+
    2023-06-30
  • Java 详解循环屏障CyclicBarrier如何实现多线程分段等待执行完成
    前言 工作中是否有这样的场景,多个线程任务,如果所有线程完成到某个阶段,你希望知道所有线程均完成该阶段。当然你使用线程计数可以实现,只是不够优雅。 所以我即:Java 多线程等待优雅...
    99+
    2024-04-02
  • Java中的CyclicBarrier怎么使用
    在Java中,CyclicBarrier是一个同步工具,它允许一组线程等待彼此达到一个共同的屏障点,然后继续执行。下面是Cyclic...
    99+
    2023-08-12
    Java CyclicBarrier
  • Java中的三种循环结构怎么用
    这篇文章主要讲解了“Java中的三种循环结构怎么用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中的三种循环结构怎么用”吧!1.for循环格式: for(初始化语句1; 判...
    99+
    2023-06-27
  • java循环语句怎么使用
    这篇文章主要介绍“java循环语句怎么使用”,在日常操作中,相信很多人在java循环语句怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java循环语句怎么使用”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-29
  • 怎么使用Java的For循环
    这篇文章主要介绍“怎么使用Java的For循环”,在日常操作中,相信很多人在怎么使用Java的For循环问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么使用Java的For...
    99+
    2024-04-02
  • C语言for循环嵌套for循环方法怎么应用
    这篇文章主要介绍“C语言for循环嵌套for循环方法怎么应用”,在日常操作中,相信很多人在C语言for循环嵌套for循环方法怎么应用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言for循环嵌套for循环...
    99+
    2023-06-30
  • MySQL中怎么使用WHILE循环模拟FOR循环
    在MySQL中,没有直接的FOR循环语句,但是可以使用WHILE循环来模拟一个FOR循环。可以使用一个变量来充当计数器,然后在WHI...
    99+
    2024-04-30
    MySQL
  • JavaScript中for循环怎么用
    这篇文章给大家分享的是有关JavaScript中for循环怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言对于for循环,相信大家再常用不过了。但是这回说下for循环是因...
    99+
    2024-04-02
  • php中for循环怎么用
    这篇文章主要为大家展示了“php中for循环怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“php中for循环怎么用”这篇文章吧。for循环//正常写法 f...
    99+
    2024-04-02
  • Java中怎么forEach循环中使用lambda表达式
    本篇文章为大家展示了Java中怎么forEach循环中使用lambda表达式,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1.数组怎么使用lambda数组不能直接在forEach中使用lambda表...
    99+
    2023-06-20
  • Java中怎么定义和使用循环队列
    Java中怎么定义和使用循环队列,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、概述:1、原理:与普通队列的区别在于循环队列添加数据时,如果其有效数据end == max...
    99+
    2023-05-30
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作