多线程编程(四)-CyclicBarrier的使用

  • CyclicBarrier的介绍

    类CyclicBarrier不仅有CountDownLatch所具有的功能,还可以是啊县屏障等待的功能,也就是阶段性同步,它在使用上的意义在与可以循环地实现线程要一起做任务的目标,而不是像类CountDownLatch一样,仅仅支持一次线程与同步点阻塞的特性。

    CyclicBarrier与CountDownLatch的区别:

    1、CountDownLatch是一个线程或者多个线程,等待两一个线程或者多个线程完成某件事情之后才能继续执行。

    2、CyclicBarrier是指多个线程之间互相等待,任何一个线程完成之前,所有的线程都必须等待。

  • 实例

    模拟田径比赛的CyclicBarrier版本

   

package com.wjg.unit_2_2_1;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Run {
    public static void main(String[] args) throws InterruptedException {
        CyclicBarrier barrier = new CyclicBarrier(10, new Runnable() {
            @Override
            public void run() {
                System.out.println("全部准备就绪!");
            }
        });
        Run run = new Run();
        for (int i = 0; i < barrier.getParties(); i++) {
            MyThread thread = run.new MyThread(barrier);
            thread.setName("运动员"+(i+1));
            thread.start();
        }
        
    }
    
    public class MyThread extends Thread{
        private CyclicBarrier barrier;

        public MyThread(CyclicBarrier barrier) {
            super();
            this.barrier = barrier;
        }

        @Override
        public void run() {
            
                try {
                    Thread.sleep((int)Math.random()*1000);
                    System.out.println(this.getName()+"到了");
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                
            
            
        }
        
        
    }
}

执行结果:

运动员1到了

运动员2到了

运动员3到了

运动员4到了

运动员5到了

运动员6到了

运动员7到了

运动员10到了

运动员9到了

运动员8到了

全部准备就绪!

  • 模拟篮球场的3V3接波场景

    

package com.wjg.unit_2_2_1;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Run {
    public static void main(String[] args) throws InterruptedException {
        CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() {
            @Override
            public void run() {
                System.out.println("3人小队组队完毕,可以接波了");
            }
        });
        Run run = new Run();
        for (int i = 0; i < 9; i++) {
            MyThread thread = run.new MyThread(barrier);
            thread.setName("玩家"+(i+1));
            thread.start();
        }
        
    }
    
    public class MyThread extends Thread{
        private CyclicBarrier barrier;

        public MyThread(CyclicBarrier barrier) {
            super();
            this.barrier = barrier;
        }

        @Override
        public void run() {
            
                try {
                    Thread.sleep((int)Math.random()*1000);
                    System.out.println(this.getName()+"到达球场,等待凑齐三人");
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                
            
            
        }
        
        
    }
}

执行结果:

玩家2到达球场,等待凑齐三人

玩家5到达球场,等待凑齐三人

玩家4到达球场,等待凑齐三人

3人小队组队完毕,可以接波了

玩家3到达球场,等待凑齐三人

玩家1到达球场,等待凑齐三人

玩家6到达球场,等待凑齐三人

3人小队组队完毕,可以接波了

玩家7到达球场,等待凑齐三人

玩家8到达球场,等待凑齐三人

玩家9到达球场,等待凑齐三人

3人小队组队完毕,可以接波了

  • 方法getNumerWaiting()

    此方法的作用是获得由几个线程已经到达了屏障点。

  • 方法isBroken()

    查询此屏障是否处于损坏状态,比如其中一个线程执行抛出了异常。则isBroken为true。 

  • 方法await(long timeout,TimeUnit unit)

    如果在执行的时间内达到parties的数量,则程序继续往下运行,否如如果出现超市,则抛出TimeoutException异常。

  • 方法getParties()

    此方法作用是获得parties的个数。

  • 方法reset()

    此方法作用是重置屏障,如果已经处于等待的线程会抛出BrokenBarrierException异常。

原文地址:https://www.cnblogs.com/niceplay/p/6475177.html