一、介绍
CyclicBarrier 线程同步屏障,他的使用场景是,等一组线程到达屏障后,然后再同时放行。
二、使用案例
@Slf4j
public class CylicBarrierExample {
private final static CyclicBarrier CYLIC_BARRIER = new CyclicBarrier(5);
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
final int num = i;
Thread.sleep(1000);
new Thread(()->{
try {
ready(num);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
public static void ready(int num) throws Exception {
log.info(" ready this thread id is {} and i is {} ",Thread.currentThread().getName(),num);
CYLIC_BARRIER.await();
log.info(" continue .... this thread id is {} and i is {} ",Thread.currentThread().getName(),num);
}
}
当调用await() 时就会检查是否达到放行标准。
三、源码分析
CyclicBarrier 内部是基于ReentrantLock 的Condition实现的。 �Condiction
3.1 阻挡线程await()
if (!timed)
trip.await();
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
而trip 就是Condiction。
3.2 何时释放栅栏
int index = --count;
if (index == 0) {
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
nextGeneration();
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
}
private void breakBarrier() {
generation.broken = true;
count = parties;
trip.signalAll();
}
3.3 小结
一组线程就相当于不同的选手在入场,condiction 这个裁判,得所以的选手入场后,才会发出指令SignalAll() ,让所有的选手任务 .放行
3.4 参考
《并发编程艺术》
|