CyclicBarrier

类介绍

A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.

CyclicBarrier是一个同步工具类,它允许一组线程在到达某个栅栏点(common barrier point)互相等待,发生阻塞,直到最后一个线程到达栅栏点,栅栏才会打开,处于阻塞状态的线程恢复继续执行.它非常适用于一组线程之间必需经常互相等待的情况。CyclicBarrier字面理解是循环的栅栏,之所以称之为循环的是因为在等待线程释放后,该栅栏还可以复用。

示例一:简单模拟一下对战平台中玩家需要完全准备好了,才能进入游戏的场景。

public class BarrierDemo {

public static void main(String[] args) {

ExecutorService service = Executors.newFixedThreadPool(5);

final CyclicBarrier barrier = new CyclicBarrier(5);

for (int i = 0; i < 5; i++) {

service.execute(new Player("玩家" + i, barrier));

}

service.shutdown();

}

}

public class Player implements Runnable {

private final String name;

private final CyclicBarrier barrier;

public Player(String name, CyclicBarrier barrier) {

this.name = name;

this.barrier = barrier;

}

public void run() {

try {

TimeUnit.SECONDS.sleep(1 + (new Random().nextInt(3)));

System.out.println(name + "已准备,等待其他玩家准备...");

barrier.await();

TimeUnit.SECONDS.sleep(1 + (new Random().nextInt(3)));

System.out.println(name + "已加入游戏");

} catch (InterruptedException e) {

System.out.println(name + "离开游戏");

} catch (BrokenBarrierException e) {

System.out.println(name + "离开游戏");

}

}

}

输出结果:

玩家0已准备,等待其他玩家准备...

玩家2已准备,等待其他玩家准备...

玩家1已准备,等待其他玩家准备...

玩家4已准备,等待其他玩家准备...

玩家3已准备,等待其他玩家准备...

玩家4已加入游戏

玩家1已加入游戏

玩家0已加入游戏

玩家3已加入游戏

玩家2已加入游戏

构造函数

CyclicBarrier有两个构造函数:

public CyclicBarrier(int parties)

public CyclicBarrier(int parties, Runnable barrierAction)

参数parties指定线程数量,当指定的线程值都到达栅栏点时,栅栏打开,线程恢复。需要注意的是,当指定的线程数量大于启动的线程数量,比如修改上例中的代码,只启动9个线程,那么所有的线程将一直处于等待状态。第二种情况是指定的线程数量小于启动的线程,上例代码,启动11个线程,那么当第十个线程到达栅栏点时,那么这十个线程就会恢复继续执行,而第十一个线程将一直处于阻塞状态。请大家自行修改代码验证。

CyclicBarrier还提供一个更高级的构造函数CyclicBarrier(int parties, Runnable barrierAction),用于在线程到达屏障时,优先执行barrierAction,方便处理更复杂的业务场景。代码如下:

示例二

public class BarrierDemo2 {

public static void main(String[] args) {

ExecutorService service = Executors.newFixedThreadPool(5);

final CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() {

public void run() {

System.out.println("所有线程已到达栅栏点");

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

for (int i = 0; i < 5; i++) {

service.execute(new Player("玩家" + i, barrier));

}

service.shutdown();

}

}

输出结果为:

玩家4已准备,等待其他玩家准备...

玩家2已准备,等待其他玩家准备...

玩家1已准备,等待其他玩家准备...

玩家0已准备,等待其他玩家准备...

玩家3已准备,等待其他玩家准备...

所有线程已到达栅栏点

玩家0已加入游戏

玩家1已加入游戏

玩家3已加入游戏

玩家4已加入游戏

玩家2已加入游戏

常用方法介绍

await()

Waits until all parties have invoked await on this barrier.

调用该方法会使当前线程在栅栏点发生阻塞,直到指定的线程数量都达到栅栏点时恢复执行

await(long timeout, TimeUnit unit)

Waits until all parties have invoked await on this barrier, or the specified waiting time elapses.

类似于await(),增加了超时时间参数。

参考如下代码:

public void run() {

try {

TimeUnit.SECONDS.sleep(1 + (new Random().nextInt(3)));

System.out.println(name + "已准备,等待其他玩家准备...");

barrier.await(200, TimeUnit.MILLISECONDS);

TimeUnit.SECONDS.sleep(1 + (new Random().nextInt(3)));

System.out.println(name + "已加入游戏");

} catch (InterruptedException e) {

System.out.println(name + "离开游戏");

} catch (BrokenBarrierException e) {

System.out.println(name + "离开游戏");

} catch (TimeoutException e) {

System.out.println(name + "连接超时");

}

}

输出结果:

玩家3已准备,等待其他玩家准备...

玩家3连接超时

玩家0已准备,等待其他玩家准备...

玩家1已准备,等待其他玩家准备...

玩家0离开游戏

玩家1离开游戏

玩家4已准备,等待其他玩家准备...

玩家2已准备,等待其他玩家准备...

玩家4离开游戏

玩家2离开游戏

上面的代码修改了Player.java里面的run()方法,当barrier在等待点出等待超时时,会抛出TimeoutException异常,同时,位于该barrier上的其他线程也将毁抛出BrokenBarrierException异常。这里说明,barrier上的线程要么同时成功要么同时失败,不存在部分成功部分失败的场景。

getNumberWaiting()

Returns the number of parties currently waiting at the barrier.

返回当前在栅栏处等待的参与者数目。此方法主要用于调试和断言。

getParties()

Returns the number of parties required to trip this barrier.

该方法可以获得构造函数中指定的需要在栅栏点阻塞的线程数量

isBroken()

Queries if this barrier is in a broken state

查询此栅栏是否处于损坏状态。

reset()

Resets the barrier to its initial state.

将barrier重置为其初始状态。如果所有参与者目前都在屏障处等待,则它们将返回,同时抛出一个 BrokenBarrierException

---------------------

作者:小鱼儿Eason

来源:CSDN

原文:https://blog.csdn.net/yin380697242/article/details/53313622

版权声明:本文为博主原创文章,转载请附上博文链接!

java线程栅栏_java多线程 栅栏CyclicBarrier相关推荐

  1. java线程钥匙_Java多线程并发编程/锁的理解

    一.前言 最近项目遇到多线程并发的情景(并发抢单&恢复库存并行),代码在正常情况下运行没有什么问题,在高并发压测下会出现:库存超发/总库存与sku库存对不上等各种问题. 在运用了 限流/加锁等 ...

  2. java 线程通讯_java多线程(五)线程通讯

    1.1. 为什么要线程通信 多个线程并发执行时,在默认情况下CPU是随机切换线程的,有时我们希望CPU按我们的规律执行线程,此时就需要线程之间协调通信. 1.2. 线程通讯方式 线程间通信常用方式如下 ...

  3. java线程池_Java多线程并发:线程基本方法+线程池原理+阻塞队列原理技术分享...

    线程基本方法有哪些? 线程相关的基本方法有 wait,notify,notifyAll,sleep,join,yield 等. 线程等待(wait) 调用该方法的线程进入 WAITING 状态,只有等 ...

  4. java线程基础_Java多线程基础

    前言 在我们工作和学习的过程中,Java线程我们或多或少的都会用到,但是在使用的过程上并不是很顺利,会遇到各种各样的坑,这里我通过讲解Thread类中的核心方法,以求重点掌握以下关键技术点: 线程的启 ...

  5. java线程入门_java多线程快速入门(一)

    1.什么是进程 比如:QQ.QQ游戏.eclipse都是进程,可以通过任务管理器查看进程 2.进程和线程区别 线程是进程的一部分,一个进程可以包含多个线程,一个线程只能属于一个进程 进程是所有线程的集 ...

  6. java线程 锁_Java多线程(二) 多线程的锁机制

    当两条线程同时访问一个类的时候,可能会带来一些问题.并发线程重入可能会带来内存泄漏.程序不可控等等.不管是线程间的通讯还是线程共享数据都需要使用Java的锁机制控制并发代码产生的问题.本篇总结主要著名 ...

  7. java线程设计模式_JAVA多线程设计模式

    漫谈UML UML 类图 类和层次结构的关系 接口与实现 聚合 访问控制 类间的关联性 顺序图 处理流程和对象间的协调 时序图 Introduction 1 Java语言的线程 Java语言的线程 何 ...

  8. java线程栅栏_Java 多线程基础 - CyclicBarrier

    我的博客 转载请注明原创出处. 序 java.util.concurrent包里有几个能帮助人们管理相互合作的线程集的类,为多线程常见的应用场景预置了抽象好的类库.在遇到这些应用场景时应该直接重用合适 ...

  9. java线程 教程_Java多线程系列教程

    Java多线程系列教程 多线程是Java中不可避免的一个重要主体.从本章开始,我们将展开对多线程的学习.接下来的内容是对Java多线程内容的讲解,涉及到的内容包括,Object类中的wait(), n ...

  10. java 线程包_Java 多线程——工具包

    JUC 首先来说说synchronized的有什么缺点. 它非常的死板.要么获取锁,要么等待锁,而且我们无法知晓此时这个锁有没有被人拿到,也不知道某个线程是否是上锁状态. 只有悲观锁.排他锁,没有乐观 ...

最新文章

  1. python基础知识选择题-99道经典练习题助你全面掌握python基础知识,附技巧答案...
  2. java判断一个类是否公共类
  3. 家庭用户的linux,一个极普通家庭用户对于ubuntu的21天使用心得
  4. python画小猪乔治_小孩挑食难搞定?试下猪肉这样炒,简单5步超下饭,比牛肉还香嫩...
  5. 导航栏对于UIScrollview以及子类所做的一些事
  6. springbot集成finereport后在web中使用iframe引用报表
  7. 《OpenCL异构计算》新版中译本派送中!
  8. Web前端工作笔记007---h5 canvas_雨滴头像合成_图像合成_合成雨滴头像
  9. 越是牛逼的人,越是不在意面子
  10. IN与EXISTS优化
  11. 12.软件架构设计:大型网站技术架构与业务架构融合之道 --- CAP理论
  12. Linux编译安装Apache
  13. 「NOIP2016」玩具谜题
  14. 原生PHP调用科大讯飞语音合成(流式版)WebAPI
  15. 飞龙在天之DB面试资料
  16. 中国重型包装行业竞争趋势与发展规模分析报告2022-2028年版
  17. smartforms 黑底白字的标签logo制作
  18. 微信公众号:weixin-js-sdk使用总结
  19. Python创建文件夹和子文件夹
  20. 计算机组成原理平均cpi怎么算_计算机组成原理计算题

热门文章

  1. zuul+ribbon实现负载均衡
  2. java调用python实现校验一串字符串是否为单词
  3. 国内首个“新基建”安全大赛启动了!
  4. Python 获取车票信息
  5. java:输入小写字母转为大写字母
  6. 程序员容易发福的原因及解决办法
  7. Linux的LILO引导程序,linux —— 启动引导程序 lilo 与 grub(示例代码)
  8. html显示vbs变量,VBS 读取 对象某属性已连接的变量的变量名
  9. ‘com.cloudera.server.cmf.TrialState‘:Cannot resolve reference to bean ‘entityManagerFactoryBean‘
  10. 采购信息记录业务知识简介