/**
* 简单仿真
* 赛马比赛
* CyclicBarrier适用于下面的情况:
* 你希望创建一组任务,他们并行的执行工作,然后在进行下一个步骤之前等待,直至所有任务都完成。
* 它使得所有的并行任务都将在栅栏处列队,因此可以一致的向前移动
*
*
* @author cxp
* @data 2016-08-31
* @modify
*
*/
import static net.mindview.util.Print.*;
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;
//马匹类,实现了Runnable接口,需要重写run()函数
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 b) {
barrier = b;
}
public synchronized int getStrides() {
return strides;
}
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
strides += rand.nextInt(3);// 产生0,1或2
}
barrier.await();//等待问题被解决的任务在锁存器上调用await(),将它们自己拦住,直至锁存器计数结束
}
} catch (InterruptedException e) {
// 一个合法的方式去退出
} catch (BrokenBarrierException e) {
// 这是我们想知道的
throw new RuntimeException(e);
}
}
//打印马匹id
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();
}
}
//赛马比赛类
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 nHorse, final int pause) {
//创建了一个匿名的Runnable作为栅栏任务,当计数为零时自动执行栅栏任务
barrier = new CyclicBarrier(nHorse, new Runnable() {
@Override
public void run() {
StringBuilder s = new StringBuilder();
for (int i = 0; i < FINISH_LINE; i++)
s.append("=");// 赛马场的栅栏
print(s);
for (Horse horse : horses)
print(horse.tracks());
for (Horse horse : horses)
if (horse.getStrides() >= FINISH_LINE) {
print(horse + "won!");
exec.shutdownNow();
return;
}
try {
TimeUnit.MILLISECONDS.sleep(pause);//当前线程休眠指定时间
} catch (InterruptedException e) {
print("barrier-action sleep interrupted");
}
}
});
for (int i = 0; i < nHorse; i++) {
Horse horse = new Horse(barrier);
horses.add(horse);
exec.execute(horse);
}
}
//主函数
public static void main(String[] args) {
int nHorses = 7;//参赛马的个数
int pause = 200;//休眠时间
//如果参数列表的长度大于零且参数值大于零,那么将第一个参数赋值给nHorses
if (args.length > 0) {
int n = new Integer(args[0]);
nHorses = n > 0 ? n : nHorses;
}
//如果参数列表的长度大于1且第二个参数值大于-1,那么将第二个参数赋值给pause
if (args.length > 1) {
int p = new Integer(args[1]);
pause = p > -1 ? p : pause;
}
//进行赛马比赛
new HorseRace(nHorses, pause);
}
}
简单仿真示例
最新推荐文章于 2024-03-03 10:59:25 发布