下面是一个 线程相互等待,都到达某一点后,继续开始执行任务的例子(测试CyclicBarrier)。
这里模拟了这样一个场景: 3个玩家同时进行通关游戏,当他们都到达或通过某一关后,才可继续往下过关。比如张三、李四、王五,他们通过每一关的时间都不相同,但是他们都必须都通关了第一关后,才能开始玩第二关;都通过了第二关,才能玩第三关... ...
写了3个类来验证这种情况,只在windows下做了测试。
1.1、GameBarrier.java 游戏关卡
1.2、GameBarrierTask.java 通关任务
1.3、GameBarrierTest.java 带有main方法的测试类,三个选手开始play game
================= 1.1 GameBarrier.java =====================
package Executor;
//游戏关卡
public class GameBarrier {
//关名称
private String barrierName;
//玩家通关时间
private int passTime;
private GameBarrier(){}
public GameBarrier(String barrierName, int passTime){
if(barrierName == null || barrierName.trim().length() == 0)
this.barrierName = "默认关";
else
this.barrierName = barrierName;
if(passTime < 1)
this.passTime = Integer.MAX_VALUE;//无限大,表示不通关
else
this.passTime = passTime;
}
public String getBarrierName() {
return barrierName;
}
public int getPassTime() {
return passTime;
}
}
========================= 1.1 end ==========================
================= 1.2 GameBarrierTask.java =====================
package Executor;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
//通关任务
public class GameBarrierTask implements Runnable {
//游戏关集合
private List<GameBarrier> gameBarriers;
//玩家名称
private String gamePlayer;
//通关控制器
private CyclicBarrier cyclicBarrier;
private GameBarrierTask() {}
public GameBarrierTask(List<GameBarrier> gameBarriers, String gamePlayer, CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
this.gameBarriers = gameBarriers;
this.gamePlayer = gamePlayer;
}
//获得当前时间
private String currenttime() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
return sdf.format(new Date()) + ": ";
}
public void run() {
try {
for (GameBarrier gameBarrier : gameBarriers) {
Thread.sleep(gameBarrier.getPassTime() * 1000);
System.out.println(currenttime() + gamePlayer + " passed game barrier " + gameBarrier.getBarrierName());
cyclicBarrier.await();
}
} catch (InterruptedException e) {
} catch (BrokenBarrierException e) {
}
}
}
========================= 1.2 end ==========================
================= 1.3 GameBarrierTest.java =====================
package Executor;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//对CyclicBarrier的测试(线程相互等待,直到都达到某一个点,然后开始继续执行)
//这个测试类进行的是:3个玩家同时进行通关游戏,当他们都到达或通过某一关后,才可以
//继续往下过关
public class GameBarrierTest {
public static void main(String[] args) {
// 建立一个带有三个玩家的通关控制器
CyclicBarrier barrier = new CyclicBarrier(3);
// 为玩家1建立通关任务
List<GameBarrier> gameBarrier1 = new ArrayList<GameBarrier>(4);
gameBarrier1.add(new GameBarrier("第一关",5));
gameBarrier1.add(new GameBarrier("第二关",2));
gameBarrier1.add(new GameBarrier("第三关",8));
gameBarrier1.add(new GameBarrier("第四关",6));
GameBarrierTask task1 = new GameBarrierTask(gameBarrier1, "张三", barrier);
// 为玩家2建立通关任务
List<GameBarrier> gameBarrier2 = new ArrayList<GameBarrier>(4);
gameBarrier2.add(new GameBarrier("第一关",1));
gameBarrier2.add(new GameBarrier("第二关",6));
gameBarrier2.add(new GameBarrier("第三关",3));
gameBarrier2.add(new GameBarrier("第四关",8));
GameBarrierTask task2 = new GameBarrierTask(gameBarrier2, "李四", barrier);
// 为玩家3建立通关任务
List<GameBarrier> gameBarrier3 = new ArrayList<GameBarrier>(4);
gameBarrier3.add(new GameBarrier("第一关",7));
gameBarrier3.add(new GameBarrier("第二关",6));
gameBarrier3.add(new GameBarrier("第三关",4));
gameBarrier3.add(new GameBarrier("第四关",3));
GameBarrierTask task3 = new GameBarrierTask(gameBarrier3, "王五", barrier);
//建立线程池,执行游戏通关任务
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(task1);
executorService.submit(task2);
executorService.submit(task3);
//关闭线程池
executorService.shutdown();
}
}
========================= 1.3 end ==========================
输出如下:
10:07:10: 李四 passed game barrier 第一关
10:07:13: 张三 passed game barrier 第一关
10:07:15: 王五 passed game barrier 第一关
10:07:17: 张三 passed game barrier 第二关
10:07:21: 王五 passed game barrier 第二关
10:07:21: 李四 passed game barrier 第二关
10:07:24: 李四 passed game barrier 第三关
10:07:25: 王五 passed game barrier 第三关
10:07:29: 张三 passed game barrier 第三关
10:07:32: 王五 passed game barrier 第四关
10:07:35: 张三 passed game barrier 第四关
10:07:37: 李四 passed game barrier 第四关
http://whitesock.iteye.com/blog/162350
public class Solver {
//
private final String[][] data;
private final CyclicBarrier barrier;
private final CountDownLatch latch;
public Solver(String[][] data) {
this.data = data;
this.barrier = new CyclicBarrier(data.length, new BarrierAction());
this.latch = new CountDownLatch(data.length);
}
public void start() {
//
for (int i = 0; i < data.length; ++i) {
new Thread(new Worker("worker" + i, this.data[i])).start();
}
//
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
String[][] data = new String[][]{{"a1", "a2", "a3"}, {"b1", "b2", "b3"}, {"c1", "c2", "c3"}};
Solver solver = new Solver(data);
solver.start();
}
private class BarrierAction implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName() + " is processing barrier action");
}
}
private class Worker implements Runnable {
//
private String name;
private String[] row;
Worker(String name, String[] row) {
this.name = name;
this.row = row;
}
public void run() {
for(int i = 0; i < row.length; i++) {
System.out.println(name + " is processing row[" + i +"]" + row[i]);
try {
barrier.await();
} catch (InterruptedException ex) {
break;
} catch (BrokenBarrierException ex) {
break;
}
}
//
latch.countDown();
}
}
}
在这个例子中,每个 worker 线程处理矩阵的一行,在处理完所有的行之前,该线程将一直在屏障处等待。处理完所有的行之后,将执行所提供的 Runnable 屏障操作,并合并这些行。CountDownLatch等待所有线程结束,继续执行主线程!