thread_CyclicBarrier回环栅栏

CyclicBarrier回环栅栏,字面意思是可循环使用(Cyclic)的屏障(Barrier)。通过它可以实现让一组线程等待至某个状态之后再全部同时执行。

它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。

叫做回环是因为当所有等待线程都被释放以后,
可以被重用。我们暂且把这个状态就叫做barrier,当调用await()方法之后,线程就处于barrier了。

await()            在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
  int await(long timeout, TimeUnit unit)     在所有参与者都已经在此屏障上调用 await 方法之前,将一直等待。
  int getNumberWaiting() 返回当前在屏障处等待的参与者数目。
  int getParties()             返回要求启动此 barrier 的参与者数目。
  boolean isBroken()       查询此屏障是否处于损坏状态。
  void reset()                 将屏障重置为其初始状态。

1.简单例子

    // 给一组线程到达一同步点,之前时被阻塞,直到最后一个线程到达障时,拦截的线程才会继续干活。
    @Test
    public void cyclicBarrier1Test() throws InterruptedException {
        // 参数表示屏障拦截的线程数量,
        CyclicBarrier c = new CyclicBarrier(2);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
                    c.await();
                } catch (Exception e) {
                }
                System.out.println(1);
            }
        }).start();
        // 第二次到达,之前到达屏障的两个线程都不会继续执行。到达后任意个线程先执行,再执行下个
        try {
            c.await();
        } catch (Exception e) {
        }
        System.out.println(2);
    }
    返回
         1
         2
    @Test
    public void cyclicBarrier2Test() throws InterruptedException {
        // 在线程到达屏障时,优先执行 A 线程
        CyclicBarrier c = new CyclicBarrier(2, new A());
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c.await();
                } catch (Exception e) {
                }
                System.out.println(1);
            }
        }).start();
        try {
            c.await();
        } catch (Exception e) {

        }
        System.out.println(2);
    }
    class A implements Runnable {
        @Override
        public void run() {
            System.out.println(3);
        }
    }    返回

3
       1
       2

2.处理复杂

CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。
  CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。isBroken方法用来知道阻塞的线程是否被中断。比如以下代码执行完之后会返回true。
    /*
    @Test
    public void cyclicBarrier3Test() throws InterruptedException, BrokenBarrierException {
        CyclicBarrier c = new CyclicBarrier(2);
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    c.await();
                } catch (Exception e) {
                }
            }
        });
        thread.start();
        thread.interrupt();
        try {
            c.await();
        } catch (Exception e) {
            System.out.println("isBroken " + c.isBroken());
        }
    }

3. 让线程同时开始

    @Test
    public void cyclicBarrier4Test() throws IOException, InterruptedException {
        CyclicBarrier barrier = new CyclicBarrier(4);
        ExecutorService executor = Executors.newFixedThreadPool(3);
        executor.submit(new Thread(new Runner(barrier, "1号选手")));
        executor.submit(new Thread(new Runner(barrier, "2号选手")));
        executor.submit(new Thread(new Runner(barrier, "3号选手")));

        executor.shutdown();
        try {
            barrier.await();
            System.out.println("isBroken ");

        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

class Runner implements Runnable {
    // 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)
    private CyclicBarrier barrier;

    private String name;

    public Runner(CyclicBarrier barrier, String name) {
        super();
        this.barrier = barrier;
        this.name = name;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(100 * (new Random()).nextInt(8));
            System.out.println(name + " 准备好了...");
            // barrier的await方法,在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
            barrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println(name + " 起跑!");
    }
}

4.CyclicBarrier和CountDownLatch的区别
   CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。
   CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。isBroken方法用来知道阻塞的线程是否被中断。比如以下代码执行完之后会返回true。

时间: 2024-12-16 03:10:23

thread_CyclicBarrier回环栅栏的相关文章

回环栅栏CyclicBarrier

通过它可以实现让一组线程等待至某个状态之后再全部同时执行.叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用.我们暂且把这个状态就叫做barrier,当调用await()方法之后,线程就处于barrier了. CyclicBarrier类位于java.util.concurrent包下,CyclicBarrier提供2个构造器: ? 1 2 3 4 5 public CyclicBarrier(int parties, Runnable barrierAction)

一维回环数组求解最大子数组问题

一.题目与要求 题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n) 二.设计思想 通过上次求解简单一维数组的最大子数组问题的解决,我们找到了一种实现时间复杂为O(n)的方法,采用的是二分法和递归

SharePoint回环检查(Loopback Check)相关问题

Loopback Check(回环检查)本来不是一个SharePoint问题,是Windows Server为了增强自身安全性在Server 2003 SP1后引入的一个功能, 在近几个月中导致了一系列问题的爆发. 一. 主要场景: 1. SharePoint站点使用了主机头(Host Header). 2. 本地访问SharePoint站点. 3. 安装下面的任意一个补丁: 1. IE累计安全补丁 (KB963027) 2. Internet Explorer 8. 3. Windows Se

ATS回环检测

ATS的回环检测是通过判断本机ip是否出现在请求头中的Via头来实现. Machine::Machine(char const* the_hostname, sockaddr const* addr):函数初始化了本机的入口ip. 如果没有配置proxy.local.incoming_ip_to_bind,这个函数第二个参数是地址存的值是一个空的sockaddr结构体.函数调用了getifaddrs,这个api可以获取系统所有的网络接口信息,存到一个ifaddrs结构体中,这个机构体是一个链表结

linux命令练习:mount fdisk swap dd创建本地回环设备

练习一   1.创建一个1G的分区,文件系统为ext4,卷标为MYDATA,块大小为1024,预留管理空间为磁盘 分区的3%,要求开机后制动挂载至/data目录,并且自动挂载的设备要使用卷标进行引用.   fdisk /dev/sda  [[email protected] ~]# fdisk /dev/sda WARNING: DOS-compatible mode is deprecated. It's strongly recommended to switch off the mode

Linux中的lo回环接口详细介绍

1.linux的网络接口之扫盲 (1)网络接口的命名 这里并不存在一定的命名规范,但网络接口名字的定义一般都是要有意义的.例如: eth0: ethernet的简写,一般用于以太网接口. wifi0:wifi是无线局域网,因此wifi0一般指无线网络接口. ath0: Atheros的简写,一般指Atheros芯片所包含的无线网络接口. lo: local的简写,一般指本地环回接口. (2)网络接口如何工作 网络接口是用来发送和接受数据包的基本设备. 系统中的所有网络接口组成一个链状结构,应用层

SharePoint 禁用本地回环的两个方法

有两种方法中,若要变通解决此问题,请根据您的具体情况使用下列方法之一. 方法 1: 指定主机名 (如果需要 NTLM 身份验证,请首选方法) 指定的主机名的映射到环回地址,并可以连接到 Web 站点在您的计算机上,请按照下列步骤操作: 设置 DisableStrictNameChecking 为 1 的注册表项. 281308 () http://support.microsoft.com/kb/281308/ 连接到 SMB 共享一台基于 Windows 2000 的计算机或基于 Window

打印数字回环

题目要求: Input a value n, then print out a n×n matrix. Example 1: Input 2, output 1 2 4 3 Example2: Input 5, output 1    2    3    4    5 16   17   18   19    6 15   24   25   20    7 14   23   22   21    8 13   12   11   10    9 思路: 把该输出划分为多个环,每个环上有4根线

java下蛇形回环矩阵的实现

前文废话:这个问题据说是腾讯之前的一道笔试题,由于当时没认真看,现在记不清这种矩阵是不是叫"蛇形回环矩阵"......请大家直接看图1,就是那个样子的矩阵. 问题描述:输入一个N,实现N×N的蛇形回环矩阵(即图1类型) (N=5时的蛇形回环矩阵) 我们先把N为奇数和N为偶数的情况分开.先来看N=3.5.7时的该类矩阵是什么情况:               看上去彼此之间并无规律,对这道题最简单粗暴的解法似乎就是构建一个二维数组,然后按人的正常思维向里填数字构建. 但是--如果用(最大