同步工具类-----循环栅栏:CyclicBarrier
2024-08-25 12:38:35
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit; public class TestCyclicBarrier {
public static class Soldier implements Runnable {
private String soldier;
private final CyclicBarrier cyclicBarrier;
private long timeout; public Soldier(CyclicBarrier cyclicBarrier, String soldier, long timeout) {
this.cyclicBarrier = cyclicBarrier;
this.timeout = timeout;
this.soldier = soldier;
} @Override
public void run() {
try {
// 等待所有士兵到齐
cyclicBarrier.await();
doWork();
// 等待所有士兵完成工作
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
} } void doWork() {
try {
// Thread.sleep(Math.abs(new Random().nextInt() % 100000));
Thread.sleep(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(soldier + ":任务完成!【用时: " + timeout / 1000 + " 秒】, " +
"当前线程:" + Thread.currentThread().getName());
}
} public static class BarrierRun implements Runnable {
boolean flag;
int N; private BarrierRun(boolean flag, int n) {
this.flag = flag;
N = n;
} @Override
public void run() {
if (flag) {
System.err.println("司令:【士兵" + N + "个,任务完成!】," +
"【当前执行线程:" + Thread.currentThread().getName() + "】");
} else {
System.err.println("司令:【士兵" + N + "个,集合完毕!】," +
"【当前执行线程:" + Thread.currentThread().getName() + "】");
flag = true;
}
}
} public static void main(String[] args) throws InterruptedException {
final int N = 10;
Thread[] soldierThreads = new Thread[N];
boolean flag = false;
// CyclicBarrier 可以接收一个Runnable类型参数作为barrierAction
//所谓barrierAction就是当计数器一次计数完成(成功通过栅栏)后的栅栏操作,系统会(在一个子任务线程中)执行的动作,但在阻塞线程被释放前是不能执行的;
//如果所有线程都成功地通过了栅栏,那么await将为每个线程返回一个唯一的到达索引号,我们可以利用这些索引来“选举”产生一个领导线程,并在下一次迭代中由该领导线程执行一些特殊的工作。
CyclicBarrier cyclicBarrier = new CyclicBarrier(N, new BarrierRun(flag, N)); System.err.println("集合队伍!"); TimeUnit.SECONDS.sleep(1); String tname;
for (int i = 0; i < N; ++i) {
System.out.println("士兵" + i + "报道!");
long timeout = (int) (1 + Math.random() * 10) * 1000;
tname = "士兵" + i;
soldierThreads[i] = new Thread(new Soldier(cyclicBarrier, tname, timeout), tname);
// soldierThreads[i].setName(tname);
soldierThreads[i].start();
/*if( i == 5){
soldierThreads[i].interrupt();
}*/
}
}
}
执行结果:
- 可见两次BarrierRun 任务分别是在 两个子任务线程中执行的。
最新文章
- [Tool]Inno Setup创建软件安装程序。
- [转载]HDU 3478 判断奇环
- 高阶c++
- 基本概率分布Basic Concept of Probability Distributions 6: Exponential Distribution
- Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- ApiWrapper
- 链接测试工具xenu link sleuth的使用
- 002医疗项目-主工程模块yycgproject三层构建(三大框架的整合)
- 获取本机IP_考虑多网卡的情况
- jquery之 off()方法
- (五)stm32工程代码HardFault异常查错调试方法
- swf2pdf转swf时字符集问题【转】
- MFC常见问题解惑
- codeblocks常用快捷键
- jQuery MVC 科室异步联动
- PHP二维数组排序函数
- poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)
- LNMP一键安装包sh脚本
- PAT (Advanced Level) 1084. Broken Keyboard (20)
- deque双端队列容器
- python之模块array
热门文章
- 横向开关(switch)
- GetModuleFileName和获取应用程序当前目录
- A memory map of an object
- python 反射 动态导入模块 类attr属性
- 万能的JDBC工具类。通过反射机制直接简单处理数据库操作
- 微信 公众号 小程序 授权 unionid 用户信息 实验总结
- ASP.NET Core 编码、web编码、网页编码 System.Text.Encodings.Web
- How to Remove A Service Entry From Win10 Service List
- July 30th 2017 Week 31st Sunday
- 一次失败的尝试hdfs的java客户端编写(在linux下使用eclipse)