下面是一个 线程相互等待,都到达某一点后,继续开始执行任务的例子(测试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等待所有线程结束,继续执行主线程!
分享到:
相关推荐
CyclicBarrier的使用以及注意事项
《java并发编程》中CountDownLatch和CyclicBarrier用法实例大全,几乎包含了所有重要的用法
用CyclicBarrier,reentrantlock,condition来完成同时购买,同步购买的功能 JUC系列之模拟抢票(N人同时抢票,票不足系统补仓,N-M人继续抢票) http://blog.csdn.net/crazyzxljing0621/article/details/77891620
CyclicBarrier是Java中的一个同步工具类,用于协调多个线程之间的同步。它的作用类似于CountDownLatch,可以让一个或多个线程等待其他线程执行完毕后再继续执行。 CyclicBarrier可以被看作是一个屏障,当所有线程都...
在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时CyclicBarrier很有用。因为该barrier在释放等待线程后可以重用,所以称它为 循环 的barrier。 CyclicBarrier 支持一个可选的 Runnable命令,...
1.2 CyclicBarrier概述 CyclicBarrier的基本用法 2.1 创建CyclicBarrier对象 2.2 await()方法 控制线程协作数量 3.1 场景介绍 3.2 使用CyclicBarrier控制线程协作 循环使用CyclicBarrier 4.1 场景介绍 4.2 使用...
主要为大家详细分析了Java并发系列之CyclicBarrier源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
NULL 博文链接:https://hubowei1.iteye.com/blog/2312471
java并发编程中CountDownLatch和CyclicBarrier的使用.pdf
java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf
CountDownLatch 和 CyclicBarrier 为线程同步的辅助工具,通过它可以做到使一条线程一直阻塞等待,直到其他线程完成其所处理的任务。
CyclicBarrier实现多个线程相互等待的案例(实现累加操作)
主要介绍了Java并发实例之CyclicBarrier的使用,涉及CyclicBarrier的介绍,以及相关的并发实例,具有一定参考价值,需要的朋友可以了解下。
CyclicBarrier类似于CountDownLatch也是个计数器,不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数,当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续...
CyclicBarrier和CountDownLatch一样,都是关于线程的计数器。用法略有不同,测试代码如下:
主要介绍了java多线程之CyclicBarrier的使用方法的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
主要介绍了Java并发编程(CyclicBarrier)实例详解的相关资料,JAVA编写并发程序的时候,我们需要仔细去思考一下并发流程的控制,如何让各个线程之间协作完成某项工作。