Java 多线程之栅栏-CyclicBarrier
我们可以通过闭锁(CountDownLatch)来同时启动一组相关线程,或等待一组相关线程的结束。可是闭锁是一次性对象,一旦进入终止状态,就不能被重置。栅栏类似于闭锁,它能够阻塞一组线程直到某个事件发生。CyclicBarrier可以使一定数量的参与线程反复地在栅栏处汇集。如果希望创建一组任务,并行地执行工作,然后在下一步开始前等待;知道直到所有工作结束。这个就可以使用栅栏(CyclicBarrier)
CyclicBarrier在并行迭代算法中是非常有用的:这种算法将一个问题拆分为一系列相对独立的子问题。当线程到达栅栏位置时将调用await方法,这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有线程被被释放,而栅栏被重置以便下次使用。如果对await调用超时或者await阻塞线程被中断,那么栅栏就被认为是打破了,所有阻塞的await调用都将抛出一个BrokenBarrierException.
public class CyclicBarrier {
private static class Generation {
boolean broken = false;
}
/** 栅栏入口的锁 */
private final ReentrantLock lock = new ReentrantLock();
/** 一直等待到跳闸的条件 */
private final Condition trip = lock.newCondition();
/** 缔约方数量 */
private final int parties;
/*跳闸时执行的命令 */
private final Runnable barrierCommand;
private Generation generation = new Generation();
/**
* 尚未等待的缔约方数量
*/
private int count;
/**
* 获取下一代
*/
private void nextGeneration() {
trip.signalAll();
count = parties;
generation = new Generation();
}
/**
* 设置当前栅栏代被打破,唤醒所有等待线程
*/
private void breakBarrier() {
generation.broken = true;
count = parties;
trip.signalAll();
}
/**
* Main barrier code, covering the various policies.
*/
private int dowait(boolean timed, long nanos)
throws InterruptedException, BrokenBarrierException,
TimeoutException {
//重入锁
final ReentrantLock lock = this.lock;
// 锁
lock.lock();
try {
final Generation g = generation;
// 如果当前一代栅栏已经跳闸则抛出异常
if (g.broken)
throw new BrokenBarrierException();
// 如果线程中断则打开栅栏
if (Thread.interrupted()) {
breakBarrier();
throw new InterruptedException();
}
// 等待线程自减
int index = --count;
// 如果当前线程已经是最后一个线程,则执行回调同时代开栅栏
if (index == 0) { // tripped
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
nextGeneration();
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
}
// 一直循环直到栅栏跳闸,打开,中断或超时
for (;;) {
try {
if (!timed)
trip.await();
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
Thread.currentThread().interrupt();
}
}
if (g.broken)
throw new BrokenBarrierException();
if (g != generation)
return index;
if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
lock.unlock();
}
}
/**
* 创建一个新的CyclicBarrier,他会在指定数量的线程都在等待是跳闸,最后一个线程通过栅栏后执行栅栏回调处理
*/
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
// 缔约方数量是指定的线程数
this.parties = parties;
//等待线程数
this.count = parties;
//栅栏命令
this.barrierCommand = barrierAction;
}
/**
*/
public CyclicBarrier(int parties) {
this(parties, null);
}
/**
* 获取缔约方数量
*/
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));
}
/**
* 查询当前栅栏是否被打破
*/
public boolean isBroken() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return generation.broken;
} finally {
lock.unlock();
}
}
/**
* 重置栅栏
*/
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();
}
}
}
加入我们有一个汽车竞速赛事,同时启动最先到达终点的汽车胜出。赛事里程是固定的,我们可以将时间分割成很小的一段,每辆汽车在这一段时间行驶的里程是不同的。
/**
*
* @author zhangwei_david
* @version $Id: Horser.java, v 0.1 2015年7月3日 下午3:15:40 zhangwei_david Exp $
*/
public class Car implements Runnable {
/**
* 汽车ID
*/
private final String id;
/**
* 门闸
*/
private static CyclicBarrier cyclicBarrier;
/**
* 里程
*/
private AtomicInteger strides = new AtomicInteger(0);
private static Random rand = new Random(47);
public Car(CyclicBarrier barrier, String id) {
cyclicBarrier = barrier;
this.id = id;
}
public int getStrides() {
return strides.get();
}
/**
* @see java.lang.Runnable#run()
*/
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
strides.set(strides.get() + rand.nextInt(3));
}
// 准备了可以开始,当门闸所有的线程都已经调用了await方法则可以继续执行
cyclicBarrier.await();
}
} catch (InterruptedException e) {
} catch (BrokenBarrierException be) {
throw new RuntimeException(be);
}
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return " [car " + id + "]";
}
public String tracks() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < getStrides(); i++) {
sb.append("-");
}
sb.append(id);
return sb.toString();
}
}
/**
* 汽车拉力赛的类
*
* @author zhangwei_david
* @version $Id: HorseRace.java, v 0.1 2015年7月3日 下午10:27:44 zhangwei_david Exp $
*/
public class CarRace {
/**
* 指定赛道长度
*/
private static final int FINISH_LINE = 75;
/**
* 赛道标尺线
*/
public static final String TRACK = "===========================================================================";
/**
* 参赛汽车
*/
private List<Car> cars = new ArrayList<Car>();
private ExecutorService service = Executors.newCachedThreadPool();
/**
* 门闸
*/
private CyclicBarrier barrier;
public CarRace(int nCars) {
/**
* 创建一个执行线程数量的CyclicBarrier,当所有现在都准备好以后则CyclicBarrier可以开闸放行,此时回调给定的barrierAction
*
*/
barrier = new CyclicBarrier(nCars, new Runnable() {
public void run() {
printEvent();
judge();
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (Exception e) {
}
}
/**
* 裁判
*/
private void judge() {
for (Car car : cars) {
if (car.getStrides() >= FINISH_LINE) {
System.out.println(car + " won!");
service.shutdownNow();
return;
}
}
}
/**
* 赛事实况
*/
private void printEvent() {
System.out.println(TRACK);
for (Car car : cars) {
System.out.println(car.tracks());
}
System.out.println(TRACK);
}
});
for (int i = 0; i < nCars; i++) {
Car car = new Car(barrier, String.valueOf(i));
cars.add(car);
service.execute(car);
}
}
public static void main(String[] args) {
new CarRace(7);
}
}
=========================================================================== --0 --1 -2 --3 -4 --5 -6 =========================================================================== =========================================================================== ---0 --1 --2 --3 -4 --5 ---6 =========================================================================== =========================================================================== ----0 ---1 ----2 ----3 --4 ---5 ----6 =========================================================================== =========================================================================== ----0 -----1 -----2 ------3 ---4 ---5 ----6 =========================================================================== =========================================================================== ----0 ------1 ------2 -------3 ----4 -----5 ----6 =========================================================================== =========================================================================== ----0 ------1 -------2 ---------3 -----4 -----5 ----6 =========================================================================== =========================================================================== -----0 --------1 --------2 ---------3 -----4 ------5 -----6 =========================================================================== =========================================================================== -------0 ---------1 ----------2 ----------3 ------4 ------5 ------6 =========================================================================== =========================================================================== -------0 ---------1 ------------2 -----------3 ------4 ------5 ------6 =========================================================================== =========================================================================== -------0 -----------1 ------------2 ------------3 --------4 -------5 -------6 =========================================================================== =========================================================================== -------0 -------------1 ------------2 --------------3 --------4 -------5 --------6 =========================================================================== =========================================================================== ---------0 ---------------1 -------------2 ---------------3 ----------4 -------5 ----------6 =========================================================================== =========================================================================== -----------0 ---------------1 --------------2 ---------------3 ----------4 --------5 ------------6 =========================================================================== =========================================================================== ------------0 ----------------1 ----------------2 ---------------3 ------------4 --------5 ------------6 =========================================================================== =========================================================================== ------------0 ----------------1 ------------------2 ---------------3 -------------4 --------5 --------------6 =========================================================================== =========================================================================== --------------0 -----------------1 --------------------2 ---------------3 ---------------4 ---------5 --------------6 =========================================================================== =========================================================================== ----------------0 -------------------1 ---------------------2 ----------------3 -----------------4 ---------5 ---------------6 =========================================================================== =========================================================================== -----------------0 --------------------1 ---------------------2 ----------------3 -----------------4 -----------5 ----------------6 =========================================================================== =========================================================================== -------------------0 --------------------1 ----------------------2 ----------------3 -----------------4 -------------5 ----------------6 =========================================================================== =========================================================================== ---------------------0 ---------------------1 ----------------------2 ------------------3 -----------------4 ---------------5 -----------------6 =========================================================================== =========================================================================== ----------------------0 ---------------------1 ----------------------2 --------------------3 -------------------4 -----------------5 -------------------6 =========================================================================== =========================================================================== -----------------------0 ----------------------1 ----------------------2 ----------------------3 -------------------4 -------------------5 ---------------------6 =========================================================================== =========================================================================== ------------------------0 ----------------------1 ------------------------2 -----------------------3 --------------------4 -------------------5 -----------------------6 =========================================================================== =========================================================================== --------------------------0 ----------------------1 --------------------------2 -------------------------3 --------------------4 -------------------5 -------------------------6 =========================================================================== =========================================================================== --------------------------0 ----------------------1 ---------------------------2 ---------------------------3 --------------------4 --------------------5 -------------------------6 =========================================================================== =========================================================================== ---------------------------0 ------------------------1 -----------------------------2 ---------------------------3 ---------------------4 ---------------------5 --------------------------6 =========================================================================== =========================================================================== ---------------------------0 -------------------------1 -------------------------------2 ---------------------------3 ----------------------4 ---------------------5 ----------------------------6 =========================================================================== =========================================================================== -----------------------------0 --------------------------1 -------------------------------2 ---------------------------3 -----------------------4 ----------------------5 ------------------------------6 =========================================================================== =========================================================================== ------------------------------0 --------------------------1 --------------------------------2 -----------------------------3 ------------------------4 ----------------------5 --------------------------------6 =========================================================================== =========================================================================== -------------------------------0 ---------------------------1 ----------------------------------2 -------------------------------3 --------------------------4 ----------------------5 ---------------------------------6 =========================================================================== =========================================================================== -------------------------------0 ---------------------------1 ----------------------------------2 ---------------------------------3 --------------------------4 ------------------------5 -----------------------------------6 =========================================================================== =========================================================================== ---------------------------------0 ----------------------------1 -----------------------------------2 ----------------------------------3 ---------------------------4 ------------------------5 -----------------------------------6 =========================================================================== =========================================================================== -----------------------------------0 ----------------------------1 -------------------------------------2 ----------------------------------3 ---------------------------4 -------------------------5 -----------------------------------6 =========================================================================== =========================================================================== -----------------------------------0 ------------------------------1 ---------------------------------------2 -----------------------------------3 ---------------------------4 ---------------------------5 -------------------------------------6 =========================================================================== =========================================================================== -----------------------------------0 ------------------------------1 ----------------------------------------2 ------------------------------------3 ---------------------------4 -----------------------------5 -------------------------------------6 =========================================================================== =========================================================================== -----------------------------------0 -------------------------------1 ------------------------------------------2 ------------------------------------3 ---------------------------4 -----------------------------5 -------------------------------------6 =========================================================================== =========================================================================== -------------------------------------0 --------------------------------1 ------------------------------------------2 -------------------------------------3 ---------------------------4 -----------------------------5 ---------------------------------------6 =========================================================================== =========================================================================== --------------------------------------0 ----------------------------------1 ------------------------------------------2 ---------------------------------------3 ---------------------------4 ------------------------------5 ---------------------------------------6 =========================================================================== =========================================================================== ----------------------------------------0 ------------------------------------1 --------------------------------------------2 ---------------------------------------3 -----------------------------4 -------------------------------5 ----------------------------------------6 =========================================================================== =========================================================================== ----------------------------------------0 --------------------------------------1 ----------------------------------------------2 ----------------------------------------3 -------------------------------4 -------------------------------5 -----------------------------------------6 =========================================================================== =========================================================================== ----------------------------------------0 ---------------------------------------1 -----------------------------------------------2 -----------------------------------------3 -------------------------------4 ---------------------------------5 -------------------------------------------6 =========================================================================== =========================================================================== -----------------------------------------0 -----------------------------------------1 ------------------------------------------------2 ------------------------------------------3 -------------------------------4 -----------------------------------5 ---------------------------------------------6 =========================================================================== =========================================================================== ------------------------------------------0 -------------------------------------------1 ------------------------------------------------2 -------------------------------------------3 ---------------------------------4 ------------------------------------5 ---------------------------------------------6 =========================================================================== =========================================================================== --------------------------------------------0 -------------------------------------------1 ------------------------------------------------2 -------------------------------------------3 ---------------------------------4 ------------------------------------5 -----------------------------------------------6 =========================================================================== =========================================================================== --------------------------------------------0 ---------------------------------------------1 --------------------------------------------------2 -------------------------------------------3 -----------------------------------4 -------------------------------------5 -------------------------------------------------6 =========================================================================== =========================================================================== ----------------------------------------------0 ----------------------------------------------1 --------------------------------------------------2 -------------------------------------------3 -------------------------------------4 -------------------------------------5 --------------------------------------------------6 =========================================================================== =========================================================================== ------------------------------------------------0 -----------------------------------------------1 ---------------------------------------------------2 ---------------------------------------------3 ---------------------------------------4 --------------------------------------5 ----------------------------------------------------6 =========================================================================== =========================================================================== -------------------------------------------------0 ------------------------------------------------1 -----------------------------------------------------2 ---------------------------------------------3 ----------------------------------------4 ----------------------------------------5 -----------------------------------------------------6 =========================================================================== =========================================================================== ---------------------------------------------------0 --------------------------------------------------1 ------------------------------------------------------2 ----------------------------------------------3 ----------------------------------------4 -----------------------------------------5 -------------------------------------------------------6 =========================================================================== =========================================================================== ----------------------------------------------------0 ---------------------------------------------------1 --------------------------------------------------------2 ------------------------------------------------3 ------------------------------------------4 ------------------------------------------5 --------------------------------------------------------6 =========================================================================== =========================================================================== ------------------------------------------------------0 -----------------------------------------------------1 ----------------------------------------------------------2 ------------------------------------------------3 ------------------------------------------4 ------------------------------------------5 ----------------------------------------------------------6 =========================================================================== =========================================================================== ------------------------------------------------------0 -------------------------------------------------------1 -----------------------------------------------------------2 ------------------------------------------------3 ------------------------------------------4 ------------------------------------------5 ------------------------------------------------------------6 =========================================================================== =========================================================================== ------------------------------------------------------0 --------------------------------------------------------1 ------------------------------------------------------------2 ------------------------------------------------3 -------------------------------------------4 -------------------------------------------5 -------------------------------------------------------------6 =========================================================================== =========================================================================== ------------------------------------------------------0 ---------------------------------------------------------1 ------------------------------------------------------------2 --------------------------------------------------3 -------------------------------------------4 ---------------------------------------------5 --------------------------------------------------------------6 =========================================================================== =========================================================================== -------------------------------------------------------0 ----------------------------------------------------------1 ------------------------------------------------------------2 ----------------------------------------------------3 ---------------------------------------------4 -----------------------------------------------5 --------------------------------------------------------------6 =========================================================================== =========================================================================== --------------------------------------------------------0 ------------------------------------------------------------1 ------------------------------------------------------------2 ------------------------------------------------------3 ---------------------------------------------4 -------------------------------------------------5 ---------------------------------------------------------------6 =========================================================================== =========================================================================== ----------------------------------------------------------0 --------------------------------------------------------------1 -------------------------------------------------------------2 ------------------------------------------------------3 -----------------------------------------------4 ---------------------------------------------------5 ----------------------------------------------------------------6 =========================================================================== =========================================================================== -----------------------------------------------------------0 ----------------------------------------------------------------1 ---------------------------------------------------------------2 ------------------------------------------------------3 -----------------------------------------------4 -----------------------------------------------------5 ------------------------------------------------------------------6 =========================================================================== =========================================================================== -------------------------------------------------------------0 -----------------------------------------------------------------1 ---------------------------------------------------------------2 ------------------------------------------------------3 -----------------------------------------------4 -----------------------------------------------------5 -------------------------------------------------------------------6 =========================================================================== =========================================================================== -------------------------------------------------------------0 -------------------------------------------------------------------1 ---------------------------------------------------------------2 -------------------------------------------------------3 -------------------------------------------------4 -------------------------------------------------------5 --------------------------------------------------------------------6 =========================================================================== =========================================================================== ---------------------------------------------------------------0 -------------------------------------------------------------------1 -----------------------------------------------------------------2 --------------------------------------------------------3 --------------------------------------------------4 -------------------------------------------------------5 --------------------------------------------------------------------6 =========================================================================== =========================================================================== ---------------------------------------------------------------0 -------------------------------------------------------------------1 -----------------------------------------------------------------2 ---------------------------------------------------------3 ----------------------------------------------------4 --------------------------------------------------------5 ----------------------------------------------------------------------6 =========================================================================== =========================================================================== -----------------------------------------------------------------0 -------------------------------------------------------------------1 -----------------------------------------------------------------2 ----------------------------------------------------------3 -----------------------------------------------------4 --------------------------------------------------------5 ------------------------------------------------------------------------6 =========================================================================== =========================================================================== ------------------------------------------------------------------0 --------------------------------------------------------------------1 -------------------------------------------------------------------2 -----------------------------------------------------------3 -------------------------------------------------------4 ---------------------------------------------------------5 --------------------------------------------------------------------------6 =========================================================================== =========================================================================== -------------------------------------------------------------------0 ----------------------------------------------------------------------1 -------------------------------------------------------------------2 -----------------------------------------------------------3 --------------------------------------------------------4 ---------------------------------------------------------5 --------------------------------------------------------------------------6 =========================================================================== =========================================================================== -------------------------------------------------------------------0 -----------------------------------------------------------------------1 --------------------------------------------------------------------2 -------------------------------------------------------------3 ----------------------------------------------------------4 ---------------------------------------------------------5 ---------------------------------------------------------------------------6 =========================================================================== [car 6] won!

浙公网安备 33010602011771号