CyclicBarrier
- 适用于如下情况:创建一组任务,并行执行工作,然后在进行下一个步骤之前等待,直至所有任务都完成(看起来有些像join())。它使得所有的并行任务都将在栅栏处列队,而CyclicBarrier可以多次重用。
- 赛马游戏
package com21concurrent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
/**
* Created by Panda on 2018/6/1.
*/
class Horse implements Runnable{
private static int counter=0;
private final int id=counter++;
private int strides=0;
private static Random random=new Random(47);
private static CyclicBarrier cyclicBarrier;
public Horse(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier=cyclicBarrier;
}
public synchronized int getStrides(){return strides;}
@Override
public void run() {
try{
while (!Thread.interrupted()){
synchronized (this){
strides+=random.nextInt(3);
}
cyclicBarrier.await();
}
}catch (InterruptedException e){
}catch (BrokenBarrierException e){
throw new RuntimeException();
}
}
public String toString(){return "Horse "+id+" ";}
public String tracks(){
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < getStrides(); i++) {
stringBuilder.append("*");
}
stringBuilder.append(id);
return stringBuilder.toString();
}
}
public class HorseRace {
static final int FINISH_LINE=75;
private List<Horse> horses=new ArrayList<>();
private ExecutorService executorService = Executors.newCachedThreadPool();
private CyclicBarrier cyclicBarrier;
public HorseRace(int nHorses,final int pause){
cyclicBarrier=new CyclicBarrier(nHorses, new Runnable() {
@Override
public void run() {
StringBuilder stringBuilder= new StringBuilder();
for (int i = 0; i <FINISH_LINE ; i++) {
stringBuilder.append("=");
}
System.out.println(stringBuilder);
for (Horse horse:horses){
System.out.println(horse.tracks());
}
for(Horse horse:horses){
if(horse.getStrides()>=FINISH_LINE){
System.out.println(horse+" won");
executorService.shutdownNow();
return;
}
}
try{
TimeUnit.MILLISECONDS.sleep(pause);
}catch (InterruptedException e){
System.out.println("barrier-action sleep interruptedException");
}
}
});
for (int i = 0; i <nHorses ; i++) {
Horse horse = new Horse(cyclicBarrier);
horses.add(horse);
executorService.execute(horse);
}
}
public static void main(String[] args) {
int nHorse=7;
int pause=200;
if(args.length>0){
int n=new Integer(args[0]);
nHorse=n>0?n:nHorse;
}
if(args.length>1){
int p=new Integer(args[1]);
pause=p>-1?p:pause;
}
new HorseRace(nHorse,pause);
}
}