java并发之 CyclicBarrier 基本使用和源码解读
CyclicBarrier类是我们平常使用的并发编程的一种。
简单理解:有三个跑道,张三跑了5米等人,李四跑了5米等人,A同学到了5米的时候,这个时候就三个人一起跑了。
个人理解:当我们的线程执行到await方法的时候会停止,而且多个线程调用await方法也会停止,直到调用的次数达到符合要求(new CyclicBarrier(5),5就是要求),各个线程的代码继续往下执行。
1:代码的简单实现
public class CyclicBarrierTest { static CyclicBarrier barrier = new CyclicBarrier(5,new Complete()); public static void main(String[] args) { for (int i=0;i<5;i++){ Thread thread = new Thread(new Worker()); thread.start(); } } private static class Complete implements Runnable{ @Override public void run() { try { System.out.println(Thread.currentThread().getName() + "======>> complete"); Thread.sleep(2000); }catch (Exception e){ e.printStackTrace(); } } } private static class Worker implements Runnable{ @Override public void run() { try { System.out.println(Thread.currentThread().getName() + "------->> init"); System.out.println(Thread.currentThread().getName() + "------->> first start"); barrier.await(); System.out.println(Thread.currentThread().getName() + "------->> first end"); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "------->> second start"); barrier.await(); System.out.println(Thread.currentThread().getName() + "------->> second end"); }catch (Exception e) { e.printStackTrace(); } } } }
运行结果

总结:CyclicBarrier 可以支持重复调用await方法,当调用的时候会阻塞当前方法,直到调用次数达到符合的次数,才能继续执行。
当在遇到await方法,会执行相同的步骤,继续等待直到符合才继续执行。
用户也可以定义一个,单独线程。CyclicBarrier 是支持符合规则以后,调用用户自定义个线程。
2:CyclicBarrier的源码解析
new CyclicBarrier(个数,线程),构造方法会把两个参数,赋值到parties、count、barrierComand等变量中。

调用await方法,会调用dowait方法。首先会先获取到ReentrantLock这是一个可重入锁,请先了解这个类,这个锁是可以重复获取的。
Generation判断该属性是否为true,不用看。Thread.interrupdated方法也不用,判断是否终止的。
index是调用了count减减的方法,自动减1。
这里面就要区分等于0和不等于0的时候了,然而当第一次调用await的时候是不等于0的,最后一次才是等于0了。
不等于0的时候,会进入一个死循环,判断timed是否为false,意思就是是否为超时获取。当不是超时的时候,会执行trip.await方法。这个方法是Condition类的。如果不了解,请先去了解。功能类似于wait、notify。
当如果大于0的时候,就调用trip.awaitNanos方法。
继续判断Generation.broken该属性是否为true。判断f是否和generation是否相等,可定是不相等的,因为在等于0的时候,会重新给generation赋值。




当执行到等于0的时候,会首先执行barrierCommand线程调用run方法,该方法不是start,不会先创建一个线程,是简单的执行run方法。
再去执行nextGeneration方法,该方法会调用trip.singnalAll方法,该方法相当于notifyall一样,对await进行通知。
count会重新赋值一下,就是为什么await能够重复使用的原因。
然后把generation重新赋值一下,感觉就像一个跳出for循环的标识一样。

ReentrantLock和Condition类会在后面给大家做详细的介绍。
总结:定义一个可重入锁,调用await方法,如果不等于就调用condition的await等待。如果等于0就调用condition的singleAll方法通知所有线程,该方法会给count重新赋值,重新定义Generation对象,让await等待的跳出for循环。
以上就是个人CyclicBarrier源码的理解,如果有不对的地方,还望大家指点出来,谢谢!

浙公网安备 33010602011771号