import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; /**
* CyclicBarrier可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 
*/
public class CyclicBarrierDemo extends Thread {
private CyclicBarrier cyclicBarrier;
public CyclicBarrierDemo(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
} @Override
public void run() {
System.out.println("子线程,"+Thread.currentThread().getName()+ " 开始写...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程,"+Thread.currentThread().getName()+ " 写完成...");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("所有线程执行完毕...");
}
public static void main(String[] args){
CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
for (int i = 0; i < 5; i++) {
CyclicBarrierDemo writer = new CyclicBarrierDemo(cyclicBarrier);
writer.start();
}
}
//子线程,Thread-0 开始写...
//子线程,Thread-1 开始写...
//子线程,Thread-2 开始写...
//子线程,Thread-3 开始写...
//子线程,Thread-4 开始写...
//子线程,Thread-1 写完成...
//子线程,Thread-0 写完成...
//子线程,Thread-2 写完成...
//子线程,Thread-4 写完成...
//子线程,Thread-3 写完成...
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
}

/**
* Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行
*/
public class CyclicBarrierDemo extends Thread {
private CyclicBarrier cyclicBarrier;
public CyclicBarrierDemo(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
} @Override
public void run() {
System.out.println("子线程,"+Thread.currentThread().getName()+ " 开始写...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程,"+Thread.currentThread().getName()+ " 写完成...");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("所有线程执行完毕...");
}
public static void main(String[] args){
CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
@Override
public void run() {
System.out.println("完成一个小目标");
}
});
for (int i = 0; i < 5; i++) {
CyclicBarrierDemo writer = new CyclicBarrierDemo(cyclicBarrier);
writer.start();
}
}
//子线程,Thread-0 开始写...
//子线程,Thread-1 开始写...
//子线程,Thread-2 开始写...
//子线程,Thread-3 开始写...
//子线程,Thread-4 开始写...
//子线程,Thread-0 写完成...
//子线程,Thread-2 写完成...
//子线程,Thread-3 写完成...
//子线程,Thread-4 写完成...
//子线程,Thread-1 写完成...
//完成一个小目标
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
}
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; /**
* CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。
* 循环栅栏 CyclicBarrier
* 可以反复使用的计数器
* 如:计数器设置为10,凑齐第一批10个线程后,计数器就会归零,然后接着凑齐下一批10个线程
*
* public CyclicBarrier(int parties, Runnable barrierAction) //计数总数,线程总数
*/
public class CyclicBarrierDemo {
public static class Soldier implements Runnable{
private String soldier;
private final CyclicBarrier cyclicBarrier;
Soldier(String soldierName, CyclicBarrier cyclicBarrier) {
this.soldier = soldierName;
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
//等待任务安排
System.out.println("开始了");
cyclicBarrier.await();
doWork();
//等待任务完成
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
//InterruptedException线程被中断
//BrokenBarrierException:表示当前的cyclicBarrier已经破损了,避免其他线程进行永久的,无所谓的等待
e.printStackTrace();
}
} void doWork() {
try {
Thread.sleep(Math.abs(new Random().nextInt()%10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(soldier+":任务完成");
}
}
public static class BarrierRun implements Runnable{
boolean flag;
int N; public BarrierRun(boolean flag, int n) {
this.flag = flag;
N = n;
} @Override
public void run() {
if (flag){
System.out.println(N+"个任务已完成!");
}else {
System.out.println("安排"+N+"个任务!");
flag = true;
}
}
}
public static void main(String[] args){
final int N = 10;
Thread[] allSoldier = new Thread[10];
boolean flag = false;
CyclicBarrier cyclic = new CyclicBarrier(N, new BarrierRun(flag, N));
System.out.println("安排任务...");
for (int i = 0; i < N; i++) {
System.out.println("任务"+i+"安排");
allSoldier[i] = new Thread(new Soldier("任务"+i,cyclic));
allSoldier[i].start();
}
}
//每运行完N个次数的任务就会执行BarrierRun任务 //安排任务...
//任务0安排
//任务1安排
//开始了
//开始了
//任务2安排
//开始了
//任务3安排
//开始了
//任务4安排
//任务5安排
//开始了
//任务6安排
//开始了
//任务7安排
//开始了
//任务8安排
//开始了
//开始了
//任务9安排
//开始了
//安排10个任务!
//任务6:任务完成
//任务3:任务完成
//任务9:任务完成
//任务5:任务完成
//任务4:任务完成
//任务0:任务完成
//任务8:任务完成
//任务7:任务完成
//任务2:任务完成
//任务1:任务完成
//10个任务已完成!
}

24.循环栅栏 CyclicBarrier的更多相关文章

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

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

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

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

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

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

  4. 循环栅栏:CyclicBarrier(司令要求任务) 读书笔记

    可以理解为循环栅栏,栅栏就是一种障碍物.假如我们将计数器设置为10,那么凑齐第一批10个线程后,计数器就会归零,然后接着凑齐下一批10个线程,这就是循环栅栏的含义. 构造器: public Cycli ...

  5. 3.1.6 循环栅栏:CyclicBarrier

    package 第三章.循环栅栏CyclicBarrier; import java.util.concurrent.BrokenBarrierException;import java.util.c ...

  6. 戏说java多线程之CyclicBarrier(循环栅栏)的CyclicBarrier(int parties)构造方法

    CyclicBarrier是JDK 1.5 concurrent包出现的一个用于解决多条线程阻塞,当达到一定条件时一起放行的一个类.我们先来看这样一个简单的需求. 现在我有一个写入数据的类,继承Run ...

  7. java并发之(4):Semaphore信号量、CounDownLatch计数锁存器和CyclicBarrier循环栅栏

    简介 java.util.concurrent包是Java 5的一个重大改进,java.util.concurrent包提供了多种线程间同步和通信的机制,比如Executors, Queues, Ti ...

  8. 线程工具类 - CyclicBarrier(循环栅栏)

    CyclicBarrier官方文档 一.原理 CyclicBarrier是另外一种多线程并发控制实用工具.它和CountDownLatch非常类似,它也可以实现线程的计数等待,但它的功能比CountD ...

  9. 并发编程 04——闭锁CountDownLatch 与 栅栏CyclicBarrier

    Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...

随机推荐

  1. 太恐怖了!黑客正在GPON路由器中利用新的零日漏洞

    即使在意识到针对GPONWi-Fi路由器的各种主动网络攻击之后,如果您还没有将其从互联网上带走,那么请小心,因为一个新的僵尸网络已加入GPON组织,该组织正在利用未公开的零日漏洞(零时差攻击). 来自 ...

  2. mac文本操作小技巧——2019年10月17日

    声明:看的别人博主写的,自己整理的,非原创,只是自用. mac文本操作技巧 官方指导文档:https://support.apple.com/zh-cn/HT201236 1.光标移动 1.1 行首. ...

  3. 如何在Sketch 54 for mac创建符号?

    Sketch 54 for mac是Mac系统平台上一个出色的数字设计绘图软件,小巧而不失功能齐全, 简约而不失强大!从最初的想法到最终的艺术品,可以通过Sketch 54 for mac来实现!现本 ...

  4. python爬取“美团美食”汕头地区的所有店铺信息

    一.目的 获取美团美食每个店铺所有的评论信息,并保存到数据库和本地 二.实现步骤 获取所有店铺的poiId 首先观察详情页的url,后面是跟着一串数字的,而这一串数字代表着每个店铺特有的id号,我们称 ...

  5. Git使用包括切换分支

  6. ELK7.1.1之插件安装

    在5.0版本之后不支持直接把插件包放入es安装目录的plugin目录下,需要单独安装:而且支持在线安装的插件很少,很多都是需要离线安装.以前的plugin变为elasticsearch-plugin ...

  7. sonarqube6.7.1使用

    1.插件安装 方法1.登入sonarqube-web安装 admin/admin 配置--应用市场--全部 英文片:administration--configuration--marketplace ...

  8. Spring-Boot"原生态"的logback

    前言 Logback是由 log4j创始人设计的又一个开源日志组件: logback当前分成三个模块: logback-core logbackclassic logback-access logba ...

  9. Docker 进入容器的4种方法

    在使用Docker创建了容器之后,大家比较关心的就是如何进入该容器了,其实进入Docker容器有好几多种方式,这里我们就讲一下常用的几种进入Docker容器的方法. 进入Docker容器比较常见的几种 ...

  10. Linux sudo 详解

    简单的说,sudo 是一种权限管理机制,管理员可以授权于一些普通用户去执行一些 root 执行的操作,而不需要知道 root 的密码.严谨些说,sudo 允许一个已授权用户以超级用户或者其它用户的角色 ...