CyclicBarrier(回环栅栏)

CyclicBarrier(回环栅栏)

通过它可以实现让一组线程等待至某个状态之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier 可以被重用。我们暂且把这个状态就叫做barrier,当调用 await()方法之后,线程就处于 barrier 了。

await()方法的重载

  • public int await():用来挂起当前线程,直至所有线程都到达 barrier 状态再同时执行后续任务;
  • public int await(long timeout, TimeUnit unit):让这些线程等待至一定的时间,如果还有线程没有到达 barrier 状态就直接让到达 barrier 的线程执行后续任务。

示例代码

public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(2);

        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+"running");
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"finish");
        },"A").start();

        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+"running");
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"finish");
        },"B").start();
    }

部分源码分析

部分成员变量

private static class Generation {
        boolean broken = false;
    }

/** The lock for guarding barrier entry */
private final ReentrantLock lock = new ReentrantLock();
/** Condition to wait on until tripped */
private final Condition trip = lock.newCondition();
/** The number of parties */
private final int parties;
/* The command to run when tripped */
private final Runnable barrierCommand;
/** The current generation */
private Generation generation = new Generation();

CyclicBarrier是通过ReentrantLock+Condition实现的工具类,里面维护这一个计算器parties来记录个数,当每个线程被barrier.await()时,线程就会被阻塞并且parties会-1操作,当parties变为0时,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);
    }
posted @   鸭梨的药丸哥  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示