Java并发编程之java.util.concurrent包——CyclicBarrier篇

概念

  • 从字面上的意思可以知道,这个类的中文意思是“循环栅栏”。大概的意思就是一个可循环利用的屏障。

  • 它的作用就是会让所有线程都等待完成后才会继续下一步行动。

  • 举个例子,就像生活中我们会约朋友们到某个餐厅一起吃饭,有些朋友可能会早到,有些朋友可能会晚到,但是这个餐厅规定必须等到所有人到齐之后才会让我们进去。这里的朋友们就是各个线程,餐厅就是 CyclicBarrier。

构造方法

public CyclicBarrier(int parties)
public CyclicBarrier(int parties, Runnable barrierAction)

解析:

  • parties 是参与线程的个数
  • 第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务

重要方法

public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException

解析:

  • 线程调用 await() 表示自己已经到达栅栏
  • BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时

下面我们就来自定义实现一个CyclicBarrier

代码如下:

public class KaneCyclicBarrier {

    private final ReentrantLock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();

    private int count =0; //批次

    private final int parties; //多少线程准备就绪?

    private Object generation = new Object();

    public KaneCyclicBarrier(int parties) {
        this.parties = parties;
    }



    public  void await(){
        final ReentrantLock lock = this.lock;
        lock.lock();
       try {
            final  Object g = generation;

           int index = ++count;
           if (index == parties) {
             nextGeneration();
             return;
           }

           while (true) {
               try {
                   condition.await();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }

               if(g!=generation){
                   return;
               }
           }
       }finally {
           lock.unlock();
       }
    }

    public void nextGeneration(){
        condition.signalAll();
        count=0;
        generation = new Object();
    }
}

测试一下,代码如下:

public class CyclicBarrier_Demo {
    public CyclicBarrier_Demo() {
    }

    public static void main(String[] args) throws InterruptedException {
        KaneCyclicBarrier barrier = new KaneCyclicBarrier(4);

        for(int i = 0; i < 100; ++i) {//假设有100个任务,每次只能有固定数量的线程去执行,可以使用这个
            (new Thread(() -> {
                barrier.await();
                System.out.println("任务开始执行");
            })).start();
            Thread.sleep(500L);
        }

    }
}

CyclicBarrier 使用场景

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

CyclicBarrier 与 CountDownLatch 区别

  • CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的
  • CountDownLatch减计数,CyclicBarrier加计数。
  • CountDownLatch 参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier 参与的线程职责是一样的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Romeo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值