循环计数器/循环栅栏/循环屏障 CyclicBarrier

news/2024/10/8 13:46:20/文章来源:https://www.cnblogs.com/cyrushuang/p/18404621

CyclicBarrier

和 CountDownLatch 有点类似,主要区别是 CyclicBarrier 可以重用,常用方法如下:

CyclicBarrier barrier = new CyclicBarrier(3); // 表示条件为:要有 3 个线程达到屏障(未指定屏障动作)
barrier.await(); // 如果没有 3 个线程到达屏障,当前线程就阻塞,直到有 3 个线程达到才恢复// 指定屏障动作
CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() {@Overridepublic void run() {System.out.println("All parties have arrived at the barrier, let's continue.");}
});

await() 底层是让 state - 1,达到栅栏的线程数量足够时,state 会重置,这样来体现可重用的。CountDown 不会重置 state

如果要使用线程池,线程池数量要和 CyclicBarrier 计数器一致

用法示例1

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.TimeoutException;public class CyclicBarrierExample {public static void main(String[] args) {// 创建一个 CyclicBarrier,设定需要3个线程到达屏障CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() {@Overridepublic void run() {// 当 3 个线程到达屏障,执行屏障动作System.out.println("All threads have reached the barrier, resuming execution.");}});// 启动3个线程,它们都会到达屏障for (int i = 0; i < 3; i++) {new Thread(new Worker(barrier)).start();}}
}class Worker implements Runnable {private CyclicBarrier barrier;public Worker(CyclicBarrier barrier) {this.barrier = barrier;}@Overridepublic void run() {try {System.out.println(Thread.currentThread().getName() + " is waiting at the barrier.");barrier.await(); // 当前线程挂起了,下面这行不会打印,直到 3 个线程达到屏障,当前线程恢复运行System.out.println(Thread.currentThread().getName() + " has passed the barrier.");} catch (InterruptedException | BrokenBarrierException e) {Thread.currentThread().interrupt();}}
}

用法示例2

执行两次,第二次执行的时候没有重新创建 CyclicBarrier,体现可重用

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.TimeoutException;public class CyclicBarrierReusableExample {public static void main(String[] args) {final int numberOfThreads = 3;final CyclicBarrier barrier = new CyclicBarrier(numberOfThreads, new Runnable() {@Overridepublic void run() {System.out.println("Barrier reached! All threads completed the phase.");}});Runnable task = () -> {try {System.out.println(Thread.currentThread().getName() + " is performing task.");Thread.sleep((long) (Math.random() * 1000));System.out.println(Thread.currentThread().getName() + " finished task and waiting at the barrier.");barrier.await();// Phase complete, proceed to the next phaseSystem.out.println(Thread.currentThread().getName() + " moving to the next phase.");} catch (InterruptedException | BrokenBarrierException e) {Thread.currentThread().interrupt();}};// Launch threads for phase 1for (int i = 0; i < numberOfThreads; i++) {new Thread(task).start();}// Wait for all threads to complete phase 1 and then start phase 2try {Thread.sleep(2000); // Simulate some delay between phases} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println("Starting next phase...");// Launch threads for phase 2, using the same barrierfor (int i = 0; i < numberOfThreads; i++) {new Thread(task).start();}}
}

改成 CountDown,因为 CountDown 的计数器不会重置,所以要创建多个 CountDown

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.BrokenBarrierException;public class CountDownLatchExample {public static void main(String[] args) {final int numberOfThreads = 3;// Define a taskRunnable task = new Runnable() {private CountDownLatch latch;public Runnable withLatch(CountDownLatch latch) {this.latch = latch;return this;}@Overridepublic void run() {try {System.out.println(Thread.currentThread().getName() + " is performing task.");// Simulate some workThread.sleep((long) (Math.random() * 1000));System.out.println(Thread.currentThread().getName() + " finished task and waiting at the latch.");latch.await();  // Wait until the latch count reaches zero// Phase complete, proceed to the next phaseSystem.out.println(Thread.currentThread().getName() + " moving to the next phase.");} catch (InterruptedException e) {Thread.currentThread().interrupt();}}};// Method to start threads with a CountDownLatchvoid startPhase(int numberOfThreads) {CountDownLatch latch = new CountDownLatch(numberOfThreads);// Start threadsfor (int i = 0; i < numberOfThreads; i++) {new Thread(task.withLatch(latch)).start();}// Release the latch after all threads have startednew Thread(() -> {try {Thread.sleep(2000); // Simulate some delay before releasing the latchSystem.out.println("Releasing the latch!");latch.countDown();  // Count down the latch to zero} catch (InterruptedException e) {Thread.currentThread().interrupt();}}).start();}// Start phase 1startPhase(numberOfThreads);// Wait for some time before starting the next phasetry {Thread.sleep(3000); // Simulate some delay between phases} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println("Starting next phase...");// Start phase 2startPhase(numberOfThreads);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/794490.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编译hello world

新建一个文件夹存放代码 在文件夹内新建一个java文件。hello.java 在文件内编写代码public class hello{public static void main(String[] args){System.out.print("hello world!");} }编译java文件,在文件目录下打开命令提示符窗口,输入:javac hello.java编译ja…

海外合规|新加坡 【数据保护新风向】你的DPO注册了吗?

数据安全已经成为了我们不可忽视的重要议题。新加坡个人数据保护委员会(PDPC)提醒,2024年9月30日之前,根据新加坡的个人资料保护法(PDPA),每个组织都必须指定至少一名数据保护官(DPO)来确保数据的合规使用。 DPO注册相关问题: 1、是否必须通过BizFile+注册我组织的DP…

Linux脚本中 指令返回值得获取,以及参数等获取

在写脚本时,经常遇到这样的问题: 如何获取当前进程号,脚本执行过的命令的进程号? 如何获取当前时间? 如何得到参数个数? 如何得到脚本中各命令的返回信息?。。。。 其实这些信息都能轻松从shell预定义的一些特殊变量获得,下面总结了一些常用的。特殊的shell变量:#获取当…

51nod 1296 有限制的排列

题目链接 学习链接 设状态 \(dp[i][j]\) 表示整数 \([1,i]\) 满足要求的排列中,最后一个数选 \(j\) 的排列数。 开一个数组记录他的状态:把前面已选好的序列中大于等于 \(j\) 的数都加一后再把 \(j\) 加到后面。#include <bits/stdc++.h> using namespace std; #define…

canvas版本中国象棋,象棋的棋子控制还是复杂一些

代码:<!Doctype html> <html lang="zh_cn"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>中国象棋</title><meta name="Keywords" content="&q…

yolo与目标检测(v1-v5)

yolo v1-v5与目标检测 深度学习经典检测方法概述 目标检测的两种方法从yolov1开始讲解,v2,v3都是在此基础上 单阶段目标检测,需要输出的就是四个值(x,y,w,h) 这样看起来很像是一个回归任务而双阶段目标检测,是先选出候选区域,在进行预测,具体细节可以看完之前文章,物体检…

Hadoop(二)Hadoop概述

概述 Hadoop是什么Hadoop是一个由Apache基金会所开发的分布式系统基础架构 分布式系统:多台服务器共同完成一个任务(例如多台计算机共同存储一份大数据) 主要解决:海量数据的存储和海量数据的分析计算问题 广义上来说,Hadoop通常是指一个更广泛的概念——Hadoop生态圈Hado…

出库申请单、其他出库单套件使用指南

出库申请单、其他出库单套件使用指南 出库申请单使用套件需要把业务类型​修改为空 点击套件展开或者保存时会自动展开套件​​ ‍ 其他出库单 如图,套件的单据,新明细会出现在第一个标签,只有一个删除行的功能。 修改新明细​中的数量会自动联动到明细信息​中 ​​ ‍博客…

程序安装:不会安装该公布程序,因为它可能不安全,请与管理员联系解决办法

程序安装:不会安装该公布程序,因为它可能不安全,请与管理员联系解决办法 删除注册表中Products下的项。该方法确实能解决问题,但为防止误删其他软件注册信息,将此法作如下改进,发现依然好使: 将注册表中 HKEY_CURRENT_USER \ Software \ Microsoft \ Installer \ Produc…

KernelWarehouse:英特尔开源轻量级涨点神器,动态卷积核突破100+ | ICML 20242A

动态卷积学习n个静态卷积核的线性混合,加权使用它们输入相关的注意力,表现出比普通卷积更优越的性能。然而,它将卷积参数的数量增加了n倍,因此并不是参数高效的。这导致不能探索n>100的设置(比典型设置n<10大一个数量级),推动动态卷积性能边界提升的同时享受参数的…

tarjan—算法的神(一)cw

本篇包含 tarjan 求强连通分量、边双连通分量、割点 部分, tarjan 求点双连通分量、桥(割边)在下一篇。伟大的 Robert Tarjan 创造了众多被人们所熟知的算法及数据结构,最著名的如:(本文的)连通性相关的 tarjan 算法,Splay-Tree,Toptree,tarjan 求 lca 等等。 注:有…

【微信小程序反编译】入门1

原创 zkaq - Tobisec 掌控安全EDU一、前言 这几天在跟着师傅一起学习微信小程序的相关知识点,前面的微信小程序的漏洞挖掘蛮简单的,但是到后面需要黑盒测试了,就需要我们对小程序进行一个反编译,进行一个代码审计相关的知识点了。 小程序的反编译相关工具有好几个,下面我给…