package java.util.concurrent;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class CyclicBarrier {
private static class Generation {
boolean broken = false;
}
/** The lock for guarding barrier entry */
private final ReentrantLock lock = new ReentrantLock();
/** Condition to wait on until tripped */
private final Condition trip = lock.newCondition();
//总线程数
private final int parties;
//栅栏方法
private final Runnable barrierCommand;
//每次运行栅栏方法后会重新创建下一个轮回类Generation
//此对象属于标识类,没有效方法
private Generation generation = new Generation();
/**每个轮回的计数器从parties到0递减,每个轮回有线程调用await时count减1
*直到0时调用栅栏方法并创建下一个轮回
*创建下一个轮回(调用nextGeneration)或终止(调用breakBarrier)CyclicBarrier是count被重置为parties的值
*/
private int count;
/**
* 运行栅栏方法后唤醒条件队列中的所有线程,重置计数器,并创建下一个轮回,
* 条件队列中所有被唤醒的线程会转存到等待队列中,只有一个线程可以获得锁运行,
* 其它线程会继续挂起,直到有锁释放
*/
private void nextGeneration() {
//代表上一个轮回完成
trip.signalAll();
// 并设置下一个轮回
count = parties;
generation = new Generation();
}
/**终止CyclicBarrier并唤醒所有条件队列的线程,此方法在持有锁的时候调用,
* 可由isBroken()方法返回
*/
private void breakBarrier() {
generation.broken = true;
count = parties;
trip.signalAll();
}
/**
* 等待会唤醒的核心方法
*/
private int dowait(boolean timed, long nanos)
throws InterruptedException, BrokenBarrierException,
TimeoutException {
final ReentrantLock lock = this.lock;
lock.lock();//必须持有锁
try {
//此刻将全局的generation保存到本地(generation在其它线程运行到栅栏处时会重新创建)
final Generation g = generation;
//一旦终止了cyclicBarrier就不允许再调用
//终止一般是因为其中一个线程被中断,或者运行栅栏方法时抛异常
if (g.broken)
throw new BrokenBarrierException();
if (Thread.interrupted()) {
//只要有一个线程被中断,那么最终会终止cyclicBarrier并唤醒所有线程
breakBarrier();
//当前线程抛出中断异常
throw new InterruptedException();
}
//等待计数器清零后执行栅栏方法
int index = --count;
//index为0代表是最后一个执行await的线程
//执行栅栏方法然后唤醒所有线程继续执行
if (index == 0) {
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();//如果抛异常会执行breakBarrier进行终止
ranAction = true;//run方法正常执行,创建下一个轮回
nextGeneration();
return 0;//当前线程返回并释放锁后其余线程得以获取锁运行
} finally {
if (!ranAction)
breakBarrier();
}
}
// 循环直到 栅栏, broken终止, 线程中断, 或等待超时
for (;;) {
try {
if (!timed)
//不超时直接调用await挂起当前线程,并释放持有的锁
trip.await();
else if (nanos > 0L)
//调用超时的方法
nanos = trip.awaitNanos(nanos);
//注:只有在signal之前中断才会抛此异常,如果在signal之后也就是运行栅栏方法后中断
//是不会抛异常的,只是线程标识为中断,当再次对此线程运行dowait时会终止cyclicBarrier
//并抛中断异常(参见此方法上文)
} catch (InterruptedException ie) {
//当前线程被中断且还没有运行到栅栏处,那么终止cyclicBarrier
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
//g 不等于 generation
//当前线程被中断,从条件队列转移到等待队列,而继续挂起
//当再次获取到锁时,在await方法中抛中断异常进入到这里发现栅栏方法已执行,
//generation对象被更新,那么设置当前线程的中断标识下次再调用此线程的await时会
//终止cyclicBarrier
Thread.currentThread().interrupt();
}
}
//已经终止抛异常
if (g.broken)
throw new BrokenBarrierException();
//当前线程因最后一个线程到达栅栏而被唤醒,此时全局的generation是
//全新对象与g不等
if (g != generation)
return index;
//当前线程因为等待超时,且还没有运行到栅栏方法,那么终止cyclicBarrier
if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
lock.unlock();
}
}
/**
* Creates a new {@code CyclicBarrier} that will trip when the
* given number of parties (threads) are waiting upon it, and which
* will execute the given barrier action when the barrier is tripped,
* performed by the last thread entering the barrier.
*
* @param parties the number of threads that must invoke {@link #await}
* before the barrier is tripped
* @param barrierAction the command to execute when the barrier is
* tripped, or {@code null} if there is no action
* @throws IllegalArgumentException if {@code parties} is less than 1
*/
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
}
/**
* Creates a new {@code CyclicBarrier} that will trip when the
* given number of parties (threads) are waiting upon it, and
* does not perform a predefined action when the barrier is tripped.
*
* @param parties the number of threads that must invoke {@link #await}
* before the barrier is tripped
* @throws IllegalArgumentException if {@code parties} is less than 1
*/
public CyclicBarrier(int parties) {
this(parties, null);
}
/**
* Returns the number of parties required to trip this barrier.
*
* @return the number of parties required to trip this barrier
*/
public int getParties() {
return parties;
}
public int await() throws InterruptedException, BrokenBarrierException {
try {
return dowait(false, 0L);
} catch (TimeoutException toe) {
throw new Error(toe); // cannot happen
}
}
public int await(long timeout, TimeUnit unit)
throws InterruptedException,
BrokenBarrierException,
TimeoutException {
return dowait(true, unit.toNanos(timeout));
}
/**
* Queries if this barrier is in a broken state.
*
* @return {@code true} if one or more parties broke out of this
* barrier due to interruption or timeout since
* construction or the last reset, or a barrier action
* failed due to an exception; {@code false} otherwise.
*/
public boolean isBroken() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return generation.broken;
} finally {
lock.unlock();
}
}
/**
* 重置CyclicBarrier以便可以循环利用
*/
public void reset() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
//终止当前轮回并唤醒条件队列的所有线程
breakBarrier(); // break the current generation
//创建新的轮回
nextGeneration(); // start a new generation
} finally {
lock.unlock();
}
}
/**
* 返回等待的线程数
*/
public int getNumberWaiting() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return parties - count;
} finally {
lock.unlock();
}
}
}