JAVA---CyclicBarrier

使用场景

有若干个线程,比如有4个线程,需要他们到达某一个点之后才能开始一起执行,假如有3个线程到达了这个点,还差1个线程没到达,此时3个线程都会进入等待状态,直到第4个线程也到达这个点之后,这4个线程才开始一起进行执行状态。

示例:

public class CyclicBarrierTest {
    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
        new Thread(
                () -> {
                    try {
                        Thread.sleep(1000);
                        System.out.println(System.currentTimeMillis() + " 线程1,开始准备。。。");
                        cyclicBarrier.await();
                        System.out.println(System.currentTimeMillis() + " 线程1,准备好了。。。");
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
        ).start();
​
        new Thread(
                () -> {
                    try {
                        Thread.sleep(2000);
                        System.out.println(System.currentTimeMillis() + " 线程2,开始准备。。。");
                        cyclicBarrier.await();
                        System.out.println(System.currentTimeMillis() + " 线程2,准备好了。。。");
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
        ).start();
​
        new Thread(
                () -> {
                    try {
                        Thread.sleep(3000);
                        System.out.println(System.currentTimeMillis() + " 线程3,开始准备。。。");
                        cyclicBarrier.await();
                        System.out.println(System.currentTimeMillis() + " 线程3,准备好了。。。");
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
        ).start();
​
        System.out.println(System.currentTimeMillis() + " 主线程,开始准备。。。");
        cyclicBarrier.await();
        System.out.println(System.currentTimeMillis() + " 主线程,准备好了。。。");
    }
}

执行结果,4个线程都到达一个点之后一起执行:

 

源码分析

CountDownLatch是基于AQS实现的;而CyclicBarrier是基于ReentrantLock重入锁实现的,当然ReentrantLock也是基于AQS实现的,非要说CyclicBarrier也是基于AQS实现的也不为过。

await()方法:

  1. 先检查前面是否已经有count个线程了,如果没有线程则会进入等待状态

  2. 当检测到屏障已经有count个线程了,则所有线程会冲出屏障继续执行(如果有Runnable参数的构造方法先执行汇总方法)

public int await() throws InterruptedException, BrokenBarrierException {
    try {
        return dowait(false, 0L);
    } catch (TimeoutException toe) {
        throw new Error(toe); // cannot happen
    }
}
​
private int dowait(boolean timed, long nanos)
    throws InterruptedException, BrokenBarrierException,
           TimeoutException {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        final Generation g = generation;
​
        if (g.broken)
            throw new BrokenBarrierException();
​
        if (Thread.interrupted()) {
            breakBarrier();
            throw new InterruptedException();
        }
​
        int index = --count;
        if (index == 0) {  // tripped
            boolean ranAction = false;
            try {
                final Runnable command = barrierCommand;
                if (command != null)
                    command.run();
                ranAction = true;
                nextGeneration();
                return 0;
            } finally {
                if (!ranAction)
                    breakBarrier();
            }
        }
​
        // loop until tripped, broken, interrupted, or timed out
        for (;;) {
            try {
                if (!timed)
                    trip.await();
                else if (nanos > 0L)
                    nanos = trip.awaitNanos(nanos);
            } catch (InterruptedException ie) {
                if (g == generation && ! g.broken) {
                    breakBarrier();
                    throw ie;
                } else {
                    // We're about to finish waiting even if we had not
                    // been interrupted, so this interrupt is deemed to
                    // "belong" to subsequent execution.
                    Thread.currentThread().interrupt();
                }
            }
​
            if (g.broken)
                throw new BrokenBarrierException();
​
            if (g != generation)
                return index;
​
            if (timed && nanos <= 0L) {
                breakBarrier();
                throw new TimeoutException();
            }
        }
    } finally {
        lock.unlock();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

傻蛋800

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

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

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

打赏作者

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

抵扣说明:

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

余额充值