CyclicBarrier和CountDownLatch类似,可以让一组任务并行的工作,然后在下一个步骤之前等待,直至所有的任务完成,但是CountDownLatch只触发一次事件,而CyclicBarrier可以多次重用
示例:
赛马游戏
class Horse implements Runnable{
private static int counter=0;
//赛马id
private final int id=counter++;
//总步长
private int strides=0;
private static Random random=new Random(47);
//栅栏
private static CyclicBarrier barrier;
public Horse(CyclicBarrier b){
barrier=b;
}
public synchronized int getStrides() {
return strides;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
strides+=random.nextInt(3);
}
barrier.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public String toString() {
return "House "+id+" ";
}
public String tracks(){
StringBuilder sb=new StringBuilder();
for (int i = 0; i <getStrides(); i++) {
sb.append("*");
}
sb.append(id);
return sb.toString();
}
}
public class HouseRace {
static final int FINISH_LINE=75;
private List<Horse>horses=new ArrayList<Horse>();
private ExecutorService exec=Executors.newCachedThreadPool();
private CyclicBarrier barrier;
public HouseRace(int nHorses,final int pause){
barrier=new CyclicBarrier(nHorses, new Runnable() {
@Override
public void run() {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < FINISH_LINE; i++) {
sb.append("=");
}
System.out.println(sb);
for (Horse horse : horses) {
System.out.println(horse.tracks());
}
for (Horse horse : horses) {
if (horse.getStrides()>=FINISH_LINE) {
System.out.println(horse+" won ");
exec.shutdownNow();
return ;
}
}
try {
TimeUnit.MILLISECONDS.sleep(pause);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
for (int i = 0; i < nHorses; i++) {
Horse horse=new Horse(barrier);
horses.add(horse);
exec.execute(horse);
}
}
public static void main(String[] args) {
int nHorses=7;
int pause=200;
new HouseRace(nHorses, pause);
}
}
所有的赛马线程每跑一次都被挂起,直到所有的赛马都处于栅栏处等待的时候,并且栅栏调用完barriarAction(CyclicBarrier初始化的第二个参数runnable)run()方法后,打破栅栏继续运行