前言
学习juc时的CyclicBarrier时遇到的一个问题,以下是遇到问题的原因以及原理
简单说一下,就是这个pareties(就是那个数字7)就是我们想要的线程数量,这里我们就以7颗龙珠为例子。
底层首先会先把pareties拷贝一个副本,然后每次在这个副本上减1,当到0就会调用
() -> System.out.println("召唤神龙成功!")
这个表达式。
.
这个是初始构造方法,这个count就是副本, 拷贝的我们的parties,底层之后的操作都是在count这个副本上进行,
每次--count, 就是每次减1, 直到0;
当我们刚好7个线程时,方法在最后调用这是显而易见的,因为await到0了; 那么当我们超过7个线程调用会发生啥呢。
当为13个线程时,最终这个表达式:
() -> System.out.println("召唤神龙成功!")
会执行,但是现在main方法还处于等待状态。
当为14个线程时,这个表达式:
() -> System.out.println("召唤神龙成功!")
被调用了两次,这时,我们可以分析一波,第一次调用应该是parties为0了,这个就跟那个7个线程的一样, 那么第二次调用时什么原因了。
而且,这里main方法并没有等待。经过多次试验发现,只要是parties(这里是7)的整数倍,main方法都不会处于等待状态,而其他情况就都会等待。
这里我们就先从await的源码入手:
因为只要调用 了 () -> System.out.println("召唤神龙成功!") 这个表达式,就表示index为0了,index为0了,就会走这个if方法,
不难发现,在这个if方法中
nextGeneration() 这个方法是肯定会执行的,我们就进去看看
这里我们发现,这里又把parties传值给了我们count,在我这方法中意思是,我这count又变成7了;
这就说明为什么7的整数倍为什么不会线程等待,因为只要是7的整数倍时,就会调用 () -> System.out.println("召唤神龙成功!") 这个表达式了,await不会等待了
而且,count又从0变为7,开始下一轮循环,而不是7的整数倍时,await方法中count不为0,就比如之前的13个线程,根据原理,要7的整数倍,也就是14时 count才为0,。