首页 > 其他分享 >CyclicBarrier(循环屏障)的使用

CyclicBarrier(循环屏障)的使用

时间:2023-01-16 09:23:41浏览次数:42  
标签:cyclicBarrier 屏障 运动员 线程 CyclicBarrier 就位 循环

一、介绍

CyclicBarrier也叫同步屏障,在JDK1.5被引入的一个同步辅助类,在API中是这么介绍的:

允许一组线程全部等待彼此达到共同屏障点的同步辅助。 循环阻塞在涉及固定大小的线程方的程序中很有用,这
些线程必须偶尔等待彼此。 屏障被称为循环,因为它可以在等待的线程被释放之后重新使用。

CyclicBarrier好比一扇门,默认情况下关闭状态,堵住了线程执行的道路,直到所有线程都就位,门才打开,让所有线程一起通过。

二、实现分析

通过上图我们可以看到 CyclicBarrier的内部是使用重入锁ReentrantLock和Condition。它有两个构造方法:
 • CyclicBarrier(int parties) :它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动屏障时执行预定义的操作。parties表示拦截线程的数量。
 • CyclicBarrier(int parties, Runnable barrierAction) :创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动屏障时执行给定的屏障操作,该操作由最后一个进入屏障的线程执行。

构造方法如下:

public CyclicBarrier(int parties, Runnable barrierAction) {
  if (parties <= 0) throw new IllegalArgumentException();
  this.parties = parties;
  this.count = parties;
  this.barrierCommand = barrierAction;
}
public CyclicBarrier(int parties) {
  this(parties, null);
}

在CyclicBarrier中最重要的方法莫过于await()方法,每个线程调用await方法告诉CyclicBarrier已经到达屏障位置,线程被阻塞。源码如下:

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

await()方法的逻辑:如果该线程不是到达的最后一个线程,则他会一直处于等待状态,除非发生以下情况:

1. 最后一个线程到达,即index == 0
2 . 超出了指定时间(超时等待)
3. 其他的某个线程中断当前线程
4. 其他的某个线程中断另一个等待的线程
5. 其他的某个线程在等待屏障超时
6. 其他的某个线程在此屏障调用reset()方法。reset()方法用于将屏障重置为初始状态。

三、案例

田径比赛,所有运动员准备好了之后,大家一起跑,代码如下

public class Demo1CyclicBarrier {
    public static void main(String[] args) {
        // 拦截线程的数量为5
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
        List<Thread> threadList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new Athlete(cyclicBarrier, "运动员" + i));
            threadList.add(t);
        }
        for (Thread t : threadList) { // 通过遍历逐一启动线程
            t.start();
        }
    }
    static class Athlete implements Runnable {
        private CyclicBarrier cyclicBarrier;
        private String name;
        public Athlete(CyclicBarrier cyclicBarrier, String name) {
                this.cyclicBarrier = cyclicBarrier;
                this.name = name;
        }
        @Override
        public void run() {
            System.out.println(name + "就位");
            try {
                // 每个线程调用await方法告诉CyclicBarrier已经到达屏障位置,线程被阻塞
                // 如果该线程不是到达的最后一个线程,则他会一直处于等待状态
                cyclicBarrier.await();
                System.out.println(name + "跑到终点。");
            } catch (Exception e) {
            }
        }
    }
}

结果如下:

运动员0就位
运动员1就位
运动员2就位
运动员3就位
运动员4就位
运动员4跑到终点。
运动员3跑到终点。
运动员2跑到终点。
运动员1跑到终点。
运动员0跑到终点。

即运动员全部就位之后才会开始跑步。

标签:cyclicBarrier,屏障,运动员,线程,CyclicBarrier,就位,循环
From: https://www.cnblogs.com/zwh0910/p/17014398.html

相关文章

  • 通过while循环 ,获得符合要求的值;输入错误的值一直循环,当值正确,才能结束循环
    第一步理解while循环packagecom.fqs.demo;publicclassWrongDemo2{publicstaticvoidmain(String[]args){inti=0;while(i<3){......
  • 循环语句
    目录循环语句while循环简单循环嵌套循环for循环简单循环嵌套循环循环的关键词循环语句while循环简单循环while条件:循环体嵌套循环while条件:while条件:......
  • ES6-遍历器与for-of循环
    一认识Iterator对象(可遍历对象)console.log([1,2]);console.log([1,2][Symbol.iterator]);//ƒvalues(){[nativecode]}//方括号的方式调用,Sym......
  • do...while循环
    do...while循环对于while语句而言,如果不满足条件,则不能进入循环,有时即使不满足条件,也至少进入一次。do...while循环和while循环相似,不同的是,do...while循环至少执行一次......
  • 同步屏障CyclicBarrier
    CyclicBarrier,根据字面意思理解:循环屏障。屏障的意思:CyclicBarrier可以让一组线程到达某个屏障点时被阻塞,直到最后一个线程到达屏障点时,屏障才会放开,所有被屏障阻塞的线程才......
  • [VueJsDev] 基础知识 - ES6循环使用手册
    ES6循环使用手册:::details目录目录​ES6循环使用手册​​​Array.1:filter()方法​​​​Array.2:forEach​​​​Array.3:for循环​​​​Array.4:map()循环​......
  • v-for 如何实现倒序循环
    <divv-for="(tpc,index)intopics.slice().reverse()":key="index"><labelfor="topic">Topics:</label><inputtype="text"name="topic"v-model="topic......
  • java for循环改造多线程例子
    1packagecom.company;23importjava.util.ArrayList;4importjava.util.List;5importjava.util.concurrent.CountDownLatch;6importjava.util.concur......
  • python教程4--判断、循环、range()函数
    1.ifelse判断if4>5:print("aa")else:print("bb")#bb#elif是elseif的意思,和Java一样a=5ifa==3:print('a是3')elifa==4:print('a是4')elif......
  • JavaScript学习笔记—循环
    JS三种循环语句while语句do-while语句for语句通常编写一个循环,需要有三个条件:(1)初始化表达式(2)条件表达式(3)更新表达式1.while循环语法while(condition){......