Java并发之CyclicBarrier浅析

CyclicBarrier 是什么?
  • CyclicBarrie允许让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
  • CyclicBarrier只能唤起一个任务,CountDownLatch可以同时唤起多个任务
  • CyclicBarrier可重用,CountDownLatch不可重用,计数值为0该CountDownLatch就不可再用了
代码分析:
public class MyTest2 {
    public static void main(String[] args) {

        CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
            System.out.println("hello world");
        });
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                new Thread(() -> {
                    try {
                        Thread.sleep((long) (Math.random() * 2000));
                        int random = new Random().nextInt(500);
                        System.out.println("hello" + random);

                        cyclicBarrier.await();
                        System.out.println("world" + random);

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }).start();
            }
        }
    }
}
/**
 * 关于CyclicBarrier的底层执行流程
 * 1. 初始化CyclicBarrier中的各种成员变量,包括parties、count以及Runnable(可选)
 * 2. 当调用await方法时,底层会先检查计数器是否已经归零,如果是的话,那么就首先执行可选的Runnable,
 * 	  接下来开始下一个generation;
 * 3. 在下一个分代中,将会重置count为parties,并且创建新的Generation实例
 * 4. 同时会调用Condition的signalAll方法,唤醒所有在屏障前面等待的线程,让其开始继续执行
 * 5. 如果计数器没有归零,那么当前的调用线程将会通过Condition的await方法,在屏障前进行等待
 * 6. 以上所有执行流程均在lock锁的控制范围内,不会出现并发情况
 */
hello234
hello51
hello479
hello world
world479
world234
world51
hello74
hello104
hello138
hello world
world138
world74
world104
hello171
hello154
hello242
hello world
world242
world171
world154
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();
            }
			// 每次进来的线程都会将count进行减1操作,在index 等于0的时候,需要执行我们的() -> {
            // System.out.println("hello world"); 语句,然后创建一个新的分代,用于下一次的操作。
            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();
                }
            }

            // 首先,会处理线程等待,会让线程等待,如果有异常就会抛出异常
            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();
        }
    }
	// 创建一个新的分代,并且初始化参数,用来执行下一次的操作
    private void nextGeneration() {
        // signal completion of last generation
        trip.signalAll();
        // set up next generation
        count = parties;
        generation = new Generation();
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值