import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
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 static CyclicBarrier barrier;
public Horse(CyclicBarrier barrier) {
this.barrier = barrier;
}
public synchronized int getStrides() {
return strides;
}
@Override
public void run() {
while (!Thread.interrupted()) {
synchronized (this) {
strides += rand.nextInt(3);
}
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public String toString() {
return "Horse " + 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 HorseRace {
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() {//匿名内部类barrier
@Override
public void run() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < FINISH_LINE; i++) {
sb.append("=");
}
System.out.println(sb);
for (Horse h : horses) {
System.out.println(h.tracks());
}
for (Horse h : horses) {
if (h.getStrides() >= FINISH_LINE) {
System.out.println(h + "won !");
exec.shutdownNow();
return;
}
}
try {
TimeUnit.MILLISECONDS.sleep(pause);
} catch (InterruptedException e) {
System.out.println(e);
}
}
});
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;
if (args.length > 0) {
int n = new Integer(args[0]);
nHorses = n > 0 ? n : nHorses;
}
if (args.length > 1) {
int p = new Integer(args[1]);
pause = p > -1 ? p : pause;
}
new HorseRace(nHorses, pause);
}
}
运行下 还是很好玩的
总结:
CountDownLatch是减数的方式
CyclicBarrier是加数的方式
CyclicBarrier可重复利用
CountDownLatch不可重复利用
不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数,
当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。
CyclicBarrier就象它名字的意思一样,可看成是个障碍,
所有的线程必须到齐后才能一起通过这个障碍。
CyclicBarrier初始时还可带一个Runnable的参数,
此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。