简述:
《Java编程思想》 第四版 P724 ~ P726
CyclicBarrier 适用于这样的情况:你希望创建一组人物,他们并行地执行工作,然后在进行下一个步骤之前等待,直至所有任务都完成
Horse.java
package com.anialy.test.concurrency.cyclicbarrier;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Horse implements Runnable {
private static int counter = 0;
private final int id = counter++;
private int strides = 0;
private static Random rand = new Random(47);
private CyclicBarrier barrier;
public Horse(CyclicBarrier b){
this.barrier = b;
}
public synchronized int getStrides(){
return strides;
}
public void run() {
try {
while(!Thread.interrupted()){
synchronized (this) {
// random strides per round
strides += rand.nextInt(3);
}
//Waits until all parties have invoked await on this barrier.
barrier.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
public String toString(){
return "Horse " + id + " ";
}
public String tracks(){
StringBuilder s = new StringBuilder();
for(int i=0; i<getStrides(); i++){
s.append("*");
}
s.append(id);
return s.toString();
}
}
HorseRace.java
package com.anialy.test.concurrency.cyclicbarrier;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class HorseRace {
private static final int FINISH_LINE = 75;
private List<Horse> horses = new ArrayList<Horse>();
private ExecutorService exec = Executors.newCachedThreadPool();
private CyclicBarrier barrier;
public HorseRace(int nHorses, final int pause){
barrier = new CyclicBarrier(nHorses, new Runnable(){
public void run() {
StringBuilder s = new StringBuilder();
for(int i=0; i<FINISH_LINE; i++){
s.append("=");
}
System.out.println(s);
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) {
System.out.println("barrier-action sleep interrupted");
}
}
});
for(int i=0; i<nHorses; i++){
Horse horse = new Horse(barrier);
horses.add(horse);
exec.execute(horse);
}
}
}
Test.java
package com.anialy.test.concurrency.cyclicbarrier;
public class Test {
public static void main(String[] args) {
int nHorses = 7;
int pause = 200;
new HorseRace(nHorses, pause);
}
}
输出:
通过使用CyclicBarrier的await在每一回合的数值变化中,直到所有子线程都完成更新才会进入下一轮线程执行。