CyclicBarrier源码理解

CyclicBarrier

在这里插入图片描述

唤醒的两种逻辑:

  1. 创建新的一代 newGeneration 时会唤醒所有线程 signalAll

  2. 打破当前代 将broken修改为true时 会唤醒所有线程 signalAll 但是这种会抛出Broken异常

    tips: 怎么才会打破当前代?就是当前线程给中断抛出异常时,就会去调用brokenBarrier方法打破当前代

CyclicBarrier里面有个变量broken,当broken为true时,表示当前‘代’被打破,来到这个代的线程会抛出BrokenException异常,

而在这个代被挂起的线程,都会被唤醒并且抛出BrokenException异常

await()方法

public int await() throws InterruptedException, BrokenBarrierException {
    try {
        return dowait(false, 0L);//false表示不支持超时机制
    } catch (TimeoutException toe) {
        throw new Error(toe); // cannot happen
    }
}

dowait()

private int dowait(boolean timed, long nanos)
        throws InterruptedException, BrokenBarrierException,
        TimeoutException {
    
    final ReentrantLock lock = this.lock;
    //加锁的原因:下面需要用到condition
    lock.lock();
    try {
        
        final Generation g = generation;

       /**/异常逻辑
        if (g.broken)
            throw new BrokenBarrierException();

        if (Thread.interrupted()) {
           
            breakBarrier();
            throw new InterruptedException();
        }
		**/
       
        //调用一次await方法就会减一次count,直到最后一个线程‘上车’就发车
        int index = --count;
       //说明人到齐了,准备发车
        if (index == 0) {  // tripped
            
            boolean ranAction = false;
            try {
				//这个是表示最后一个线程到达需要完成的动作
                final Runnable command = barrierCommand;
                
                if (command != null)
                    command.run();
				
                ranAction = true;
				//开启新的一代,唤醒所有给挂起的线程
                /**{1.唤醒所有线程
                    2.重置count
                    3.开启新的一代
                }**/
                nextGeneration();
                return 0;
            } finally {
                if (!ranAction)
                  
                    breakBarrier();
            }
        }

        //如果当前线程不是最后一个线程的话,就走下面自旋的逻辑
        for (;;) {
            try {
               
                if (!timed)
                    //如果不是支持超时等待的话,就走condition的await()逻辑,会释放锁,加入条件队列尾部,挂起自己等待被唤醒
                    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();
                }
            }

            //执行到这里,1.最后一个线程开启了新的一代,唤醒了所有线程
            //2.gengration被打破,异常唤醒
            //3.当前线程支持超时机制,并且超时了,被加入阻塞队列,然后拿到锁了给唤醒了
            
            //这个是 2 那种情况
            if (g.broken)
               
                throw new BrokenBarrierException();

            //这里是 1 那种情况
            if (g != generation)
                
                return index;

           
			//这里是 3 那种情况
            if (timed && nanos <= 0L) {
               
                breakBarrier();
               
                throw new TimeoutException();
            }
        }
    } finally {
        lock.unlock();
    }
}
正常唤醒逻辑:nextGeneration()
private void nextGeneration() {
   
    // signal completion of last generation
    trip.signalAll();
    
    count = parties;

    generation = new Generation();
}
异常唤醒逻辑:breakGeneration()
private void breakBarrier() {
    //将代中的broken设置为true,表示这一代是被打破了的,再来到这一代的线程,直接抛出异常.
    generation.broken = true;
    //重置count为parties
    count = parties;
    //将在trip条件队列内挂起的线程 全部唤醒,唤醒后的线程 会检查当前代 是否是打破的,
    //如果是打破的话,接下来的逻辑和 开启下一代 唤醒的逻辑不一样.
    trip.signalAll();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值