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();
}*/
}
}
}

执行结果:

  1. 可见两次BarrierRun 任务分别是在 两个子任务线程中执行的。

同步工具类-----循环栅栏:CyclicBarrier的更多相关文章

  1. JUC常用同步工具类——CountDownLatch,CyclicBarrier,Semaphore

    在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 一.CountDownLa ...

  2. 同步工具类 CountDownLatch 和 CyclicBarrier

    在开发中,一些异步操作会明显加快执行速度带来更好的体验,但同时也增加了开发的复杂度,想了用好多线程,就必须从这些方面去了解 线程的 wait() notify() notifyall() 方法 线程异 ...

  3. Java核心知识点学习----线程同步工具类,CyclicBarrier学习

    线程同步工具类,CyclicBarrier日常开发较少涉及,这里只举一个例子,以做备注.N个人一块出去玩,相约去两个地方,CyclicBarrier的主要作用是等待所有人都汇合了,才往下一站出发. 1 ...

  4. Java并发编程原理与实战二十七:循环栅栏:CyclicBarrier

    昨天我们学习了倒计数功能的等待,今天我们学习的是循环栅栏:CyclicBarrier.下面我们就开始吧: 1.CyclicBarrier简介CyclicBarrier,是JDK1.5的java.uti ...

  5. java 利用同步工具类控制线程

    前言 参考来源:<java并发编程实战> 同步工具类:根据工具类的自身状态来协调线程的控制流.通过同步工具类,来协调线程之间的行为. 可见性:在多线程环境下,当某个属性被其他线程修改后,其 ...

  6. Java并发(基础知识)——显示锁和同步工具类

    显示锁                                                                                     Lock接口是Java ...

  7. 多线程之倒计时器CountDownLatch和循环栅栏CyclicBarrier

    1.倒计时器CountDownLatch CountDownLatch是一个多线程控制工具类.通常用来控制线程等待,它可以让一个线程一直等待知道计时结束才开始执行 构造函数: public Count ...

  8. 《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&并发容器类&同步工具类,消费者模式

    上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Has ...

  9. java高并发系列 - 第17天:JUC中的循环栅栏CyclicBarrier常见的6种使用场景及代码示例

    这是java高并发系列第17篇. 本文主要内容: 介绍CyclicBarrier 6个示例介绍CyclicBarrier的使用 对比CyclicBarrier和CountDownLatch Cycli ...

随机推荐

  1. PyCharm添加Selenium与Appium依赖

  2. Python交互式编辑器ipthon notebook jupyter

    简介 IPython NoteBook(jupyter)是一个综合的交互式编程环境,比原本python命令进入的交互式环境要强大很多,总之就是炫酷加实用,浏览器中写Python代码,访问源端linux ...

  3. webpack学习笔记丁点积累

    webpack是什么? https://webpack.js.org/concepts/ https://code.tutsplus.com/tutorials/introduction-to-web ...

  4. yum 安装LAMP

    一.安装 MySQL 首先来进行 MySQL 的安装.打开超级终端,输入: [root@localhost ~]# yum install mysql mysql-server 安装完毕,让 MySQ ...

  5. 贪心算法和动态规划[zz]

    http://www.cnblogs.com/asuran/archive/2010/01/26/1656399.html 贪心算法 1.贪心选择性质 所谓贪心选择性质是指所求问题的整体最优解可以通过 ...

  6. Python学习---Django的验证码

    [更多参考] http://www.cnblogs.com/wupeiqi/articles/4786251.html

  7. cmd pyhton

    在cmd中运行python解释器: 1.同时执行多条指令,可在多条指令中间使用 & 连接 >>> print('123') &print('223') 123 223

  8. c/c++ 中#ifndef和#endif的作用及使用

    有时候我们在编程的时候,希望有些代码在我们需要时编译,不需要时不编译,也就是让它快速注释,这时候即可以考虑#ifdef和#endif,它们会使我们的编译器进行选择性编译.使用方法如下: #includ ...

  9. Github的commit规范

    参考链接:GIT写出好的 commit message 基本要求 第一行应该少于50个字. 随后是一个空行 第一行题目也可以写成:Fix issue #8976 永远不在 git commit 上增加 ...

  10. jersey之get,put,post,delete简单使用

    要使用jersey首先要有相应的依赖包,获取方法有很多,本地下载依赖文件或maven获取,这里假设你的环境已经搭建好了.要使用jersey首先要初始化一个client客户端,下面是最简单的一个get请 ...