同步工具类-----循环栅栏:CyclicBarrier
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 任务分别是在 两个子任务线程中执行的。

同步工具类-----循环栅栏:CyclicBarrier的更多相关文章
- JUC常用同步工具类——CountDownLatch,CyclicBarrier,Semaphore
在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 一.CountDownLa ...
- 同步工具类 CountDownLatch 和 CyclicBarrier
在开发中,一些异步操作会明显加快执行速度带来更好的体验,但同时也增加了开发的复杂度,想了用好多线程,就必须从这些方面去了解 线程的 wait() notify() notifyall() 方法 线程异 ...
- Java核心知识点学习----线程同步工具类,CyclicBarrier学习
线程同步工具类,CyclicBarrier日常开发较少涉及,这里只举一个例子,以做备注.N个人一块出去玩,相约去两个地方,CyclicBarrier的主要作用是等待所有人都汇合了,才往下一站出发. 1 ...
- Java并发编程原理与实战二十七:循环栅栏:CyclicBarrier
昨天我们学习了倒计数功能的等待,今天我们学习的是循环栅栏:CyclicBarrier.下面我们就开始吧: 1.CyclicBarrier简介CyclicBarrier,是JDK1.5的java.uti ...
- java 利用同步工具类控制线程
前言 参考来源:<java并发编程实战> 同步工具类:根据工具类的自身状态来协调线程的控制流.通过同步工具类,来协调线程之间的行为. 可见性:在多线程环境下,当某个属性被其他线程修改后,其 ...
- Java并发(基础知识)——显示锁和同步工具类
显示锁 Lock接口是Java ...
- 多线程之倒计时器CountDownLatch和循环栅栏CyclicBarrier
1.倒计时器CountDownLatch CountDownLatch是一个多线程控制工具类.通常用来控制线程等待,它可以让一个线程一直等待知道计时结束才开始执行 构造函数: public Count ...
- 《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&并发容器类&同步工具类,消费者模式
上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Has ...
- java高并发系列 - 第17天:JUC中的循环栅栏CyclicBarrier常见的6种使用场景及代码示例
这是java高并发系列第17篇. 本文主要内容: 介绍CyclicBarrier 6个示例介绍CyclicBarrier的使用 对比CyclicBarrier和CountDownLatch Cycli ...
随机推荐
- JAVA中获取文件的大小和文件的扩展名
一.获取文件扩展名(该段代码来自博客园网站装男人的博客https://www.cnblogs.com/nanrenzhuang/archive/2013/05/19/6315546.html) pub ...
- volley2--volley的使用和架构
图片: 下面只是笼统的介绍,大家可以对比自己的想法,看看自己是不是有什么考虑不周的(如果是你实现这样一个框架的话) 1,Request的设计,我们在得到response之后,我们可能根据项目需求希望有 ...
- Week1——JavaEE
本科目标 首先,对我来说自己想走的方向是JavaWeb后台开发,因此JavaEE对我来说也是比较重要的,想学好这门课.进一步巩固自己现有的基础知识,完善自己的项目经验,更加熟悉开发流程.在框架方面我还 ...
- android端的ormlite框架
安卓端有很多优秀的数据库框架来操作sqlite,如ormlite框架,这个框架可以用来实现表到对象的解析和转化. 使用: 首先去官网下载两个jar包,core和android(如果在安卓端开发的话), ...
- vue3.0端口号修改
module.exports = { // 基本路径 baseUrl: '/', // 输出文件目录 outputDir: 'dist', // 生产环境是否生成 sourceMap 文件 produ ...
- java笔记--增加虚拟机内存
--如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3877243.html "谢谢-- 为避免大型应用程序因虚拟机内存不足而无法 ...
- 【转】网络管理员必知之:IP地址划分
1.IP地址分类 IP地址有四个段,包括网络标识和主机标识两部分:netid+hostid. IP地址应用分为A.B.C三类,D.E类是保留和专用的. ...
- python传递参数给shell
#格式化字符 print "hello, %s" % ('mm') #传递参数 n="192.168.200.2" os.popen('ping %s -c 2 ...
- 在python中逐行读取大文件
在我们日常工作中,难免会有处理日志文件的时候,当文件小的时候,基本不用当心什么,直接用file.read()或readlines()就可以了,但是如果是将一个10G大小的日志文件读取,即文件大于内存的 ...
- 使用泛型和内部静态类实现栈(FILO,先进后出)
package tuple; /** * 泛型实现的栈,FILO * @author Youjie * * @param <T> */ public class LinkedStack&l ...