package org.rui.thread.newc;
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;
/**
* 赛马游戏 CyclicBarrier
*
* @author lenovo
*
*/
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;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
//每场比赛都会加上随机 跨过的数字 0,1 or 2
strides += rand.nextInt(3);// produces 0,1 or 2
}
// 等待所有的马都准备完毕,当所有的马向前移动时,cyclicBarrier将自动调用runnable栅栏动作任务,按顺序显示马和终点的位置
barrier.await();
}
} catch (InterruptedException e) {
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
}
}
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 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) {
//System.out.println("strides:@@@@@@@" + horse.getStrides());
if (horse.getStrides() >= FINISH_LINE) {//
System.out.println(horse + "赢得!");
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);//每个马都分配一个barrier
horses.add(horse);
exec.execute(horse);
}
}
/**
* main
*
* @param args
*/
public static void main(String[] args) {
int nHorses = 7; //指定马的数量
int pause = 200;//停顿时间
String[] arg = {};
if (arg.length > 0) {// optional argument
int n = new Integer(arg[0]);
nHorses = n > 0 ? n : nHorses;
}
if (arg.length > 1) {// optional argument
int p = new Integer(arg[1]);
pause = p > -1 ? p : pause;
}
// 竞赛
new HorseRace(nHorses, pause);
}
}
/**
===========================================================================
**0
**1
*2
**3
*4
**5
*6
===========================================================================
**0
***1
*2
**3
*4
***5
***6
===========================================================================
***0
****1
***2
***3
**4
*****5
****6
===========================================================================
*****0
****1
*****2
****3
**4
******5
****6
===========================================================================
******0
****1
******2
*****3
****4
******5
*****6
===========================================================================
******0
******1
******2
******3
****4
*******5
*****6
===========================================================================
*******0
******1
*******2
******3
*****4
********5
*******6
===========================================================================
********0
******1
********2
*******3
*******4
*********5
*********6
===========================================================================
********0
******1
*********2
*******3
*********4
*********5
*********6
===========================================================================
**********0
*******1
**********2
********3
*********4
***********5
*********6
===========================================================================
**********0
*******1
************2
*********3
*********4
*************5
*********6
===========================================================================
************0
*******1
*************2
***********3
**********4
***************5
***********6
===========================================================================
************0
********1
*************2
*************3
***********4
***************5
*************6
===========================================================================
**************0
********1
*************2
*************3
*************4
...
...
...此处省略打印线
===========================================================================
**********************************************************************0
*******************************************************1
******************************************************************2
***********************************************************************3
***********************************************************************4
***********************************************************************5
*************************************************************6
===========================================================================
***********************************************************************0
*******************************************************1
*******************************************************************2
*************************************************************************3
***********************************************************************4
*************************************************************************5
***************************************************************6
===========================================================================
************************************************************************0
********************************************************1
*******************************************************************2
***************************************************************************3
***********************************************************************4
***************************************************************************5
****************************************************************6
Horse3 赢得!
*/
一个容易理解的张孝祥老师讲解例子
package test;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* CyclicBarrier 应用
* @author lenovo
*
*/
public class CyclicBarrierTest {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3); // 三个线程同时到达
for (int i = 0; i < 3; i++) {
Runnable runnable = new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程"
+ Thread.currentThread().getName()
+ "即将到达集合地点1,当前已有"
+ (cb.getNumberWaiting() + 1)
+ "个已到达"
+ (cb.getNumberWaiting() == 2 ? "都到齐了,继续走啊"
: "正在等候"));
try {
cb.await();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程"
+ Thread.currentThread().getName()
+ "即将到达集合地点2,当前已有"
+ (cb.getNumberWaiting() + 1)
+ "个已到达"
+ (cb.getNumberWaiting() == 2 ? "都到齐了,继续走啊"
: "正在等候"));
try {
cb.await();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程"
+ Thread.currentThread().getName()
+ "即将到达集合地点3,当前已有"
+ (cb.getNumberWaiting() + 1)
+ "个已到达"
+ (cb.getNumberWaiting() == 2 ? "都到齐了,继续走啊"
: "正在等候"));
try {
cb.await();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
/**
* output:
线程pool-1-thread-3即将到达集合地点1,当前已有1个已到达正在等候
线程pool-1-thread-1即将到达集合地点1,当前已有2个已到达正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有3个已到达都到齐了,继续走啊
线程pool-1-thread-2即将到达集合地点2,当前已有1个已到达正在等候
线程pool-1-thread-1即将到达集合地点2,当前已有2个已到达正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有3个已到达都到齐了,继续走啊
线程pool-1-thread-3即将到达集合地点3,当前已有1个已到达正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已到达正在等候
线程pool-1-thread-1即将到达集合地点3,当前已有3个已到达都到齐了,继续走啊
*/