Java并发编程之CyclicBarrier
一、场景描述
有四个游戏玩家玩游戏,游戏有三个关卡,每个关卡必须要所有玩家都到达后才能允许通过。其实这个场景里的玩家中如果有玩家A先到了关卡1,他必须等到其他所有玩家都到达关卡1时才能通过,也就是说线程之间需要相互等待。这和CountDownLatch的应用场景有区别,CountDownLatch里的线程是到了运行的目标后继续干自己的其他事情,而这里的线程需要等待其他线程后才能继续完成下面的工作。
二、CyclicBarrier介绍
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
CyclicBarrier类有两个常用的构造方法:
1. CyclicBarrier(int parties)
这里的parties也是一个计数器,例如,初始化时parties里的计数是3,于是拥有该CyclicBarrier对象的线程当parties的计数为3时就唤醒,注:这里parties里的计数在运行时当调用CyclicBarrier:await()时,计数就加1,一直加到初始的值
2. CyclicBarrier(int parties, Runnable barrierAction)
这里的parties与上一个构造方法的解释是一样的,这里需要解释的是第二个入参(Runnable barrierAction),这个参数是一个实现Runnable接口的类的对象,也就是说当parties加到初始值时就出发barrierAction的内容。
代码示例
package com.itmyhome;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* 玩家类
* @author itmyhome
*
*/
class Player implements Runnable {
private CyclicBarrier cyclicBarrier;
private int id;
public Player(int id, CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
this.id = id;
}
@Override
public void run() {
try {
System.out.println("玩家" + id + "正在玩第一关...");
cyclicBarrier.await();
System.out.println("玩家" + id + "进入第二关...");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public class CyclicBarrierTest {
public static void main(String[] args) {
// CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
CyclicBarrier cyclicBarrier = new CyclicBarrier(4,
new Runnable() {
@Override
public void run() {
System.out.println("所有玩家进入第二关!");
}
});
for (int i = 0; i < 4; i++) {
new Thread(new Player(i, cyclicBarrier)).start();
}
}
}
输出结果:
玩家0正在玩第一关...
玩家3正在玩第一关...
玩家2正在玩第一关...
玩家1正在玩第一关...
所有玩家进入第二关!
玩家3进入第二关...
玩家1进入第二关...
玩家2进入第二关...
玩家0进入第二关...
CyclicBarrier和CountDownLatch的区别
- CountDownLatch: 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。
- CyclicBarrier: N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
- CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。
- CountDownLatch:减计数方式,CyclicBarrier:加计数方式
Java并发编程之CyclicBarrier的更多相关文章
- Java并发编程之CAS
CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术.简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替 ...
- Java并发编程之CAS第一篇-什么是CAS
Java并发编程之CAS第一篇-什么是CAS 通过前面几篇的学习,我们对并发编程两个高频知识点了解了其中的一个—volatitl.从这一篇文章开始,我们将要学习另一个知识点—CAS.本篇是<凯哥 ...
- Java并发编程之CAS二源码追根溯源
Java并发编程之CAS二源码追根溯源 在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理. 本篇是<凯哥(凯哥Java: ...
- Java并发编程之CAS第三篇-CAS的缺点及解决办法
Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...
- Java并发编程之set集合的线程安全类你知道吗
Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥Java:kagejava)并发编程学习> ...
- Java并发编程之Lock
重入锁ReentrantLock 可以代替synchronized, 但synchronized更灵活. 但是, 必须必须必须要手动释放锁. try { lock.lock(); } finally ...
- Java并发编程之AQS
一.什么是AQS AQS(AbstractQueuedSynchronize:队列同步器)是用来构建锁或者其他同步组件的基础框架,很多同步类都是在它的基础上实现的,比如常用的ReentrantLock ...
- Java并发编程之synchronized关键字
整理一下synchronized关键字相关的知识点. 在多线程并发编程中synchronized扮演着相当重要的角色,synchronized关键字是用来控制线程同步的,可以保证在同一个时刻,只有一个 ...
- Java 并发编程之 Condition 接口
本文部分摘自<Java 并发编程的艺术> 概述 任意一个 Java 对象,都拥有一个监视器方法,主要包括 wait().wait(long timeout).notify() 以及 not ...
随机推荐
- beego——模板处理
beego的模板处理引擎采用的是Go内置的html/template包进行处理,而且beego的模板处理逻辑是采用了缓存编译方式, 也就是所有的模板会在beego应用启动的时候全部编译然后缓存在map ...
- POJ - 1904 King's Quest (强连通)
题意:有N个王子,每个王子有任意个喜欢的妹子,巫师会给出一个方案:每个妹子都嫁给一个王子.但是国王希望知道:每个王子能在哪些妹子中择偶而不影响其他王子择偶. 分析:设王子为x部,妹子为y部,假设有匹配 ...
- h5打开App的方法。
在浏览器中: 法1: location.href = `${scheme}`;//location跳转App是几乎所以情况都支持的. 法2: var ifr = document.createElem ...
- 反射_获取字段的Description信息
var memInfo = enumType.GetType().GetMember(enumType.ToString()); var attributes = memInfo[0].GetCust ...
- MySQL-5.7 高阶语法及流程控制
1.标签语句 [begin_label:] BEGIN [statement_list] END [end_label] [begin_label:] LOOP statement_list END ...
- AMBA总线基础知识简介
AMBA:Advanced Microcontroller Bus Architecture,是ARMA公司的片内互联总线协议. 1995 - AMBA1.0 APB外设总线及ASB系统总线发布. 1 ...
- Cisco交换机设备配置镜像端口
查看交换机端口的基本情况,输入命令 show ip int bri,可以查看端口状态 FastEthernet表示百兆以太网端口,GigabitEthernet表示千兆以太网端口. 进入全局模式 设置 ...
- 字符串的hash匹配
如果要比较字符串是否相等,首先想到的是KMP算法,但是hash更加简洁易于编写,hash的目的是把一串字符转化成一个数字,用数字来比较是否相等.我让mod=912837417 Base=127,防止h ...
- Linux下针对路由功能配置iptables的方法详解
作为公司上网的路由器需要实现的功能有nat地址转换.dhcp.dns缓存.流量控制.应用程序控制,nat地址转换通过iptables可以直 接实现,dhcp服务需要安装dhcpd,dns缓存功能需要使 ...
- SpringBoot 表单验证
Valid 注解 JSR 303 校验框架注解类: • @NotNull 注解元素必须是非空 • @Null 注解元素必须是空 • @Digits 验证数字构成是否合法 • @Future 验证是否在 ...