CyclicBarrier

本文介绍了一个使用Java CyclicBarrier实现的多线程同步案例。模拟了三个玩家在通过游戏关卡时的同步过程,确保所有玩家都通过同一关卡后才能进入下一关。通过具体的代码实现了线程间的等待和同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面是一个 线程相互等待,都到达某一点后,继续开始执行任务的例子(测试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 第四关




[url]http://whitesock.iteye.com/blog/162350[/url]

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等待所有线程结束,继续执行主线程!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值