首页 > 其他分享 >CyclicBarrier并发工具类

CyclicBarrier并发工具类

时间:2022-11-04 12:31:48浏览次数:109  
标签:Thread 到达 并发 屏障 线程 new 工具 CyclicBarrier


作用

让一 组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开放,所有被屏障拦截的线程才会继续运行。

核心方法

  • CyclicBarrier(int parties):默认构造方法,parties参数表示屏障拦截的线程数量
  • CyclicBarrier(int parties, Runnable barrierAction):barrierAction表示屏障开放的时候会优先执行barrierAction线程,会直接使用最后到达屏障的那个线程来执行barrierAction。
  • await():告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞,直到所有线程到达屏障后,屏障开放一起执行
  • reset():重置计数器
  • getNumberWaiting方法可以获得Cyclic-Barrier 阻塞的线程数量
  • isBroken()方法用来了解阻塞的线程是否被中断

应用场景

CyclicBarrier可以用于多线程计算数据,最后合并计算结果的场景。

示例

package com.xiaolyuh;

import com.alibaba.fastjson.JSON;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CyclicBarrier;

/**
* CyclicBarrier并发工具类
*
* @author yuhao.wang3
* @since 2019/6/27 15:52
*/
public class CyclicBarrierTest {

public static void main(String[] args) {
Random random = new Random();
Map<String, Long> map = new ConcurrentHashMap<>();
CyclicBarrier cyclicBarrier = new CyclicBarrier(4, () -> {
System.out.println(Thread.currentThread().getName() + " 3所有线程到达屏障的时候,优先执行barrierAction线程。。。。。。。");
System.out.println(Thread.currentThread().getName() + " 3" + JSON.toJSONString(map));
});

for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
Thread.sleep(200 + random.nextInt(200));
System.out.println(Thread.currentThread().getName() + " 1等待所有线程到达屏障------------");
map.put(Thread.currentThread().getName(), Thread.currentThread().getId());
cyclicBarrier.await();
System.out.println(Thread.currentThread().getName() + " 2所有线程到达屏障的时候,开始执行业务代码================");
} catch (Exception e) {
e.printStackTrace();
}

}).start();
}

try {
cyclicBarrier.await();
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " 主线程完成");
} catch (Exception e) {
e.printStackTrace();
}
}
}

输出结果:

Thread-1  1等待所有线程到达屏障------------
Thread-0 1等待所有线程到达屏障------------
Thread-2 1等待所有线程到达屏障------------
Thread-2 3所有线程到达屏障的时候,优先执行barrierAction线程。。。。。。。
Thread-2 3{"Thread-0":13,"Thread-1":14,"Thread-2":15}
Thread-2 2所有线程到达屏障的时候,开始执行业务代码================
Thread-1 2所有线程到达屏障的时候,开始执行业务代码================
Thread-0 2所有线程到达屏障的时候,开始执行业务代码================
main 主线程完成

源码

/**
* Main barrier code, covering the various policies.
*/
private int dowait(boolean timed, long nanos)
throws InterruptedException, BrokenBarrierException, TimeoutException {
// 使用ReentrantLock来做并发控制
final ReentrantLock lock = this.lock;
lock.lock();
try {
final Generation g = generation;

if (g.broken)
throw new BrokenBarrierException();
// 验证线程的中断状态(y有作用)
if (Thread.interrupted()) {
breakBarrier();
throw new InterruptedException();
}
// 计数器减一
int index = --count;
// 计数器减到0需要放行
if (index == 0) { // tripped
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
// 修改放行状态和唤醒左右等待线程
nextGeneration();
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
}

// loop until tripped, broken, interrupted, or timed out
for (;;) {
try {
if (!timed)
// 没有设置过期时间就一直等待
trip.await();
else if (nanos > 0L)
// 调用有超时机制的等待方法
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
// We're about to finish waiting even if we had not
// been interrupted, so this interrupt is deemed to
// "belong" to subsequent execution.
Thread.currentThread().interrupt();
}
}

if (g.broken)
throw new BrokenBarrierException();

if (g != generation)
return index;

if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
lock.unlock();
}
}

参考

《java并发编程的艺术》

源码

​https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases​

spring-boot-student-concurrent 工程

layering-cache

​为监控而生的多级缓存框架 layering-cache​​这是我开源的一个多级缓存框架的实现,如果有兴趣可以看一下


标签:Thread,到达,并发,屏障,线程,new,工具,CyclicBarrier
From: https://blog.51cto.com/u_15861563/5823593

相关文章

  • CyclicBarrier和CountDownLatch的区别
    CountDownLatch是两组线程,第一组负责计数器减一,第二组是阻塞线程,当第一组线程将计数器减到0时,第二组线程才开始执行,放行是由第三方控制;CyclicBarrier是只有一组线程,只有当所......
  • js 密码强度检测工具
    效果:  新建一个密码强度检测工具文件 password-strength.js://hasnumberconsthasNumber=(number)=>newRegExp(/[0-9]/).test(number);//hasmixofs......
  • Unity 常用功能代码工具集
    Unity常用功能整理安卓摄像头的调用请求与拍摄、截图//////————————SakuraNeko————————//////博客园:https://www.cnblogs.com/sakuraneko//......
  • Rocksdb 日志分析工具 -- 性能和稳定性分析
    文章目录​​1.前言​​​​2.工具使用细节​​​​3.如何制作一个自己的python-package​​​​3.1项目配置文件​​​​3.1.1LICENSE文件​​​​3.2README.md文......
  • Java核心工具库Guava介绍以及Optional和Preconditions使用进行非空和数据校验
    场景GuavaGuava项目是Google公司开源的Java核心库,它主要是包含一些在Java开发中经常使用到的功能,如数据校验、不可变集合、计数集合,集合增强操作、I/O、缓存、字......
  • 桌面取色器小工具
    color-picker-app基于Tauri+Vue3的取色器软件,可对桌面进行取色项目地址:https://github.com/Hxy1992/color-picker-app软件下载:https://github.com/Hxy1992/c......
  • vue3.0新的打包工具vite
    vitevite是基于esbuild预构建的,esbuild是用GO语言编写的,比js编写的打包器预构建快10-100倍,js跟go语言相比太慢了。与webpack相比:vite服务器启动速度比webpack快,由于vite......
  • less编译工具koala(考拉)和rem的使用
    1.使用rem的前提是要提前设置好页面的根节点的大小:(两种选择任意一种即可)(1).在body中设置font-size:16px(2).<script>(function(){varhtml=......
  • 【Unity3D日常开发】Unity3D工具之UnityForSVN
    大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。一、前言在日常开发中,常常会用到SVN或者Git作为项目版本协同管理的工具,可是在Unity......
  • 以太坊调用工具类
    packageeasyJava.controller;importcom.alibaba.fastjson.JSON;importcom.fasterxml.jackson.core.JsonProcessingException;importcom.fasterxml.jackson.databi......