记录一下CountDownLatch 和 CyclicBarrier 的使用例子

Unity安卓打包实战:SDK与JDK配置全攻略 本文详细介绍了Unity安卓打包过程中SDK与JDK的配置方法,包括工具下载、安装步骤、环境变量设置及常见错误排查。通过实战指南帮助开发者快速完成Unity安卓打包环境搭建,提升开发效率。 阅读详情

之前的面试有被提到过java.util.concurrent中解决并发的问题。

看Thinking in Java 学习一下其中一些构件的使用。

本文记录关于CountDownLatch  和 CyclicBarrier 使用的小例子。

CountDownLatch 典型用法就是将一个程序分成n个相互独立的可解决的任务(锁存器)

public class CountDownLatchDemo {
	static final int SIZE = 10;
	public static void main(String[] args){
		ExecutorService exec = Executors.newCachedThreadPool();
		// All must share a single CountDownLatch object
		CountDownLatch latch = new CountDownLatch(SIZE);// 初始化CountDownLatch,并初始化计数值为100
		for (int i = 0; i < 10; i++) {
			exec.execute(new WaitingTask(latch));
		}
		for (int i = 0; i < SIZE; i++) {
			exec.execute(new TaskPortion(latch));
		}
		System.out.println("Launched all tasks");
		exec.shutdown();// Quit when all tasks complete
	}
}

注意:
  1. CountDownLatch 被设计只能触发一次,初始化时要传入一个初始计数值
  2. 初始计数值不能被重置,当任务完成时,这个锁存器调用 CountDown() 方法来减小计数值
  3. 等待被解决的任务调用 latch 的 await() 方法进入阻塞,直到正在进行的任务的计数器为 0 
上面的主函数先执行 10 个 WaitingTask(顾名思义,需要等待执行的任务),然后执行另一个任务 TaskPortion 。下面给出两个任务类的实现代码:

class TaskPortion implements Runnable {
	private static int counter = 0;
	private final int id = counter++;
	private static Random rand = new Random(47);
	private final CountDownLatch latch;
	public TaskPortion(CountDownLatch latch) {// must initialize latch in constructor because of final latch
		// TODO Auto-generated constructor stub
		this.latch = latch;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			doWork();
			latch.countDown();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private void doWork() throws InterruptedException {
		// TODO Auto-generated method stub
		TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));// rand.nextInt() is safe 
		System.out.println(this + "completed");
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return String.format("%1$-3d ", id);
	}
}

注意:

  1. TaskPortion 的 doWork() 方法随机休眠一段时间来模拟部分工作的完成
  2. 当模拟任务完成后,计数值减一
  3. TaskPortion 内包含一个静态 Random 对象,有可能多线程同时调用 Random.nextInt() ,但它是线程安全的。当然可以移除 static 限定符来解决
class WaitingTask implements Runnable {
	private static int counter = 0;
	private final int id = counter++;
	private final CountDownLatch latch;
	public WaitingTask(CountDownLatch latch) {
		// TODO Auto-generated constructor stub
		this.latch = latch;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			latch.await();
			System.out.println("Latch barrier passed for " + this.toString());
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println(this + " interrupted");
		}
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return String.format("WaitingTask %1$-3d ", id);
	}
}

注意:

  1. WaitingTask 调用了 latch 的 await() 方法,会等待 TaskPortion 中计数值将为 0 在执行。
结果截图:


CyclicBarrier 可以多次重用,下一步骤在当前步骤完成前等待。

public class HorseRace {
	static final int FINISH_LINE = 10;
	private List<Horse> horses = new ArrayList<>();
	private ExecutorService exec = Executors.newCachedThreadPool();
	private CyclicBarrier barrier;
	public HorseRace(int nHorses, final int pause) {
		// TODO Auto-generated constructor stub
		barrier = new CyclicBarrier(nHorses, new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				StringBuilder s = new StringBuilder();
				for (int i = 0; i < FINISH_LINE; i++) {
					s.append("=");// The fence on the racetrack
				}
				System.out.println(s);
				for(Horse horse : horses){
					System.out.println(horse.tracks());
				}
				for(Horse horse : horses)
					if (horse.getStrides() >= FINISH_LINE) {
						System.out.println(horse + "won!");
						exec.shutdownNow();
						return;
					}
				try {
					TimeUnit.MILLISECONDS.sleep(pause);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					System.out.println("barrier-action sleep interrupted");
				}
			}
		});
		for (int i = 0; i < nHorses; i++) {
			Horse horse = new Horse(barrier);
			horses.add(horse);
			exec.execute(horse);
		}
	}
	
	public static void main(String[] args){
		int nHorses = 3;
		int pause = 200;
		if (args.length > 0) {
			int n = new Integer(args[0]);
			nHorses = n > 0 ? n : nHorses;
		}
		if (args.length > 1) {
			int p = new Integer(args[1]);
			pause = p > 0 ? p : pause;
		}
		new HorseRace(nHorses, pause);
	}
	
	
}

注意:

  1. 向 CyclicBarrier 提供了一个“栅栏动作”,即一个Runnable,以匿名内部类的形式创建;
  2. Runnable 的动作当计数值(此例中为马的数量 nHorse)到达 0 时 自动执行
  3. FINISH_LINE 定义了赛道长度,打印“=”
  4. 打印各匹马的轨迹,当有马大于等于赛道长度时,停止所有任务(shutdownNow() , 与 shutdown() 的区别)
  5. 每一个 Horse 对象都由一个线程控制,来控制进度轨迹。
class Horse implements Runnable {
	private static int counter = 0;
	private final int id = counter++;
	private int strides = 0;
	
	private static Random rand = new Random(47);
	private static CyclicBarrier barrier;
	public Horse(CyclicBarrier barrier) {
		// TODO Auto-generated constructor stub
		this.barrier = barrier;
	}
	public synchronized int getStrides(){return strides;}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			while (!Thread.interrupted()) {
				synchronized(this){
					strides += rand.nextInt(3); // Produces 0, 1, or 2
				}
				barrier.await();
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			// An legitimate way to exit
			e.printStackTrace();
		} catch (BrokenBarrierException e){
			// This is the way we want to know about
			throw new RuntimeException(e);
		}
	}	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Horse " + id + " ";
	}
	public String tracks(){
		StringBuilder s = new StringBuilder();
		for (int i = 0; i < getStrides(); i++) {
			s.append("*");
		}
		s.append(id);
		return s.toString();
	}
}


Windows Server双机热备实战:用IIS+ARR+NLB搭建高可用Web服务(附避坑指南) 本文详细介绍了在Windows Server环境下,利用IIS、ARR(Application Request Routing)和NLB(Network Load Balancing)构建高可用Web服务的实战方案。通过双机热备架构,实现从网络层到应用层的全面冗余与智能流量分发,并提供了关键的配置步骤、常见避坑指南及性能调优建议,确保企业级Web服务的连续性与可靠性。 阅读详情

相关推荐

新版本大疆智图4.5 永久许可摄影测量建模软件

大疆智图支持常见格式的成果输出,包括 TIFF 正射影像和高程模型、LAS 格式点云,以及 B3DM、OSGB、OBJ 等六种常用格式的三维模型,还包括 DXF 和 SHP 等格式的等高线。大疆智图 DJI Terra是领先的三维重建软件,提供先进的技术和简单的操作,一站式解决方案,从航线规划到数据的获取,以及模型重建、数据分析等都提供独一无二的支持,优化项目工程,提供自动化优势,获得更有效智能的决策和行动,最终用户可以获得理想的结果,减轻工作压力,提高作业效率。质量报告和剖面查看功能有助于分析点云质量。

qq_62821232的博客 6903

CountDownLatch、CyclicBarrier、Semaphore案例

CountDownLatch、CyclicBarrier、Semaphore案例

inexaustible的博客 573

Excel炒股党必备:手把手教你用Power Query免费获取并刷新股票历史数据

本文详细介绍了如何利用Excel中的Power Query工具免费获取并自动刷新股票历史数据,特别适合Excel炒股党。从环境配置、数据源选择到实战操作,手把手教你建立智能数据管道,实现高效投资分析。通过参数化股票代码和定时刷新功能,大幅提升数据更新效率。

weixin_26767391的博客 654

大白话说java并发工具类-CountDownLatch,CyclicBarrier

1. 倒计时器CountDownLatch 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join方法,让主线程等待被join的线程执行完之后,主线程才能继续往下执行。当然,使用线程间消息通信机制也可以完成。其实,java并发工具类中为我们提供了类似“倒计时”这样的工具类,可以十分方便的完成所说...

weixin_34125592的博客 515

AI编程实战:用Spec Coding与Codex半小时重构全栈项目

这次我们来看一个能显著提升全栈开发效率的实战方法:利用 AI 编程工具 Codex 和 Spec Coding 工作流,将原本需要数周甚至一个月的全栈项目重构工期,压缩到半小时级别。这不是概念探讨,而是基于现有工具链的、可立即上手的工程实践。 对于前端开发者或全栈工程师而言,面对老旧项目重构、技术栈升级或从零搭建新项目时,最大的痛点往往是重复性、模式化的代码编写工作。手动编写 CRUD 接口、页面组件、状态管理和联调测试,耗时费力且容易出错。而 AI 辅助编程的核心价值,正是在于将开发者从这些“体力活”中解

weixin_33525298的博客 290

Android实现自动输入文本效果 (附完整源码)

Android实现自动输入文本效果 (附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 416

Java并发常用类CyclicBarrier、CountDownLatch应用场景示例

 CyclicBarrier 类的应用示例:如开启5个线程,在每个线程内部打印输出"Hello World",5个线程先全部输出"Hello",之后再输出"World"。 import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class Pri...

WindfallSheng的博客 369

星敏感器:卫星姿态测量的“星空导航仪”

在卫星、航天器和深空探测器的姿态控制系统中,星敏感器(Star Tracker) 是最精确的姿态测量设备之一。它通过识别恒星的位置,计算出航天器在惯性空间中的三轴姿态,精度可达 角秒级(arcsecond),是许多高精度任务(如遥感、天文观测、深空探测)的核心传感器。

ScilogyHunter的博客 3701

CyclicBarrier,CountDownLatch源码解析和使用示例

CyclicBarrier,CountDownLatch源码解析和使用示例 CyclicBarrier:循环栅栏 拦截一定数量的线程,当所有线程都到达某个点后,再开始运行。 比如生活中要开展某个活动,但是要等所有人齐了才能开始就类似于此场景。 先来看一道题目:有三个线程,要求三个线程先轮流输出hello,输完后再输出world CyclicBarrier实现: class solution{ public static void main(String[] args){ //拦截3个

qq_45066013的博客 277

MATLAB - Gazebo 联合仿真 —— 使用 UR10 机械臂检测和采摘水果

本示例演示如何在 Gazebo 物理模拟器中设置 Universal Robotics UR10 机械臂和仿真环境。您需要配置一个机器人从树上摘苹果的仿真环境。本示例演示如何利用这些工具箱,使用 Universal Robotics UR10 机械手模拟机器人检测并从树上摘取苹果。Robotics System Toolbox™ - 在 Simulink® 和 Gazebo 中对机械手进行建模、规划和模拟。Navigation Toolbox™ - 生成三维环境的占用图。

机器人控制与仿真应用 4183

【异常】Hermes Agent调用z.ai接口失败(余额不足)API call failed (attempt 1/3): RateLimitError [HTTP 429]

补充说明:同步尝试解析接口对应网页时,出现“网页解析失败,可能是不支持的网页类型,请检查网页或稍后重试”提示,该提示不影响核心报错排查,仅作为辅助信息。

奶爸的编程之路,也就一周冷个三天 1197

CountDownLatch、CyclicBarrier、Semaphore使用

1.CountDownLatch案例 让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒 CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。 当计数器的值变为零时,因调用await方法被阻塞的线程会被唤醒,继续执行 //未使用CountDownLatch public class CountDownLatchDemo { public static void main(String[] ar...

jun_422的专栏 238

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Java闭锁(CountDownLatch)和栅栏(CyclicBarrier)

假设一场短跑比赛,使用多个线程代表每个运动员的状态和比赛过程,需要每个运动员同时出发,打印出每个关键节点的时间作为参考: CountDownLatch 来自API文档 所有方法 Modifier and Type Method and Description void await()导致当前线程等到锁存器计数到零,除非线程是 interrupted 。 boolean await(long timeout, TimeUnit unit)使当前线程等待直到锁存器计数到零为止,除非线程.

烦了pomole 398

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

CyclicBarrier和CountDownLatch的用法与区别

前言 CyclicBarrier和CountDownLatch这两个工具都是在java.util.concurrent包下,并且平时很多场景都会使用到。 本文将会对两者进行分析,记录他们的用法和区别。 CountDownLatch CountDownLatch是一个非常实用的多线程控制工具类,称之为“倒计时器”,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。 CountDownL...

Deegue 1万+

CountDownLatch 和 CyclicBarrier

1,CountdownLatch适用于所有线程通过某一点后通知方法,而CyclicBarrier则适合让所有线程在同一点同时执行 2,CountdownLatch利用继承AQS的共享锁来进行线程的通知,利用CAS来进行–,而CyclicBarrier则利用ReentrantLock的Condition来阻塞和通知线程。

gpx2001的博客 1628

CountDownLatch、CyclicBarrier 和 Semaphore

主要介绍了Java并发编程中三个重要的同步工具:CountDownLatch、CyclicBarrier和Semaphore,它们的原理,使用场景...

程序员Forlan的博客 1803

CyclicBarrier & CountDownLatch

可重复使用:它的设计允许在多个循环或阶段中重复使用,当一组线程到达屏障后,屏障会自动重置,进入下一轮等待。是一次性的:它的计数器一旦到达 0,就无法再次使用,只能用于一次性任务协调。如果需要再次使用,必须创建新的实例。

青衫客36的博客 1081

简述CyclicBarrier、CountDownLatch和Semaphore

文章目录前言一. 概念篇1.1 CyclicBarrier1.2. CountDownLatch1.3. Semaphore二. 案例篇2.1. CyclicBarrier2.2. CountDownLatch2.3. Semaphore三. 深入篇3.1. CyclicBarrier3.2. CountDownLatch3.3. Semaphore3.4. CAS3.5. AQS 前言

米二的博客 3759

CountDownLatch与CyclicBarrier

CountDownLatch与CyclicBarrier区别 CountDownLatch JUC包下的并发工具类CountDownLatch,CountDownLatch为递减计数器,用于控制一个线 程等待多个线程。维护一个计数器count,表示需要等待的事件数量,countdown方法递减计数 器,表示事件发生,调用await()方法的线程会一直阻塞直到计数器为零,或者等待中的线程中断, 或者等待超时 CyclicBarrier CyclicBarrier,循环栅栏可以让一组线程等待至某个状态之后再全部

weixin_44442186的博客 1288

countdownlatch和cyclicbarrier原理详解

CyclicBarrier 的主要实现原理是什么?CyclicBarrier 内部维护了一个计数器和一个栅栏状态,每次调用 await() 方法都会将计数器减 1,当计数器的值为 0 时,所有线程都已到达同步点,会被唤醒继续执行后续操作,并且栅栏状态会被重置。CountDownLatch 内部维护了一个计数器,初始值为构造函数中传入的值,即 count,每次调用 countDown() 方法都会将计数器减 1,当计数器的值为 0 时,所有调用 await() 方法等待的线程都会被唤醒,继续执行后续操作。

lonely_baby的博客 1448

【多线程并发编程】十三 CountDownLatch和CyclicBarrier

介绍CountDownLatch和CyclicBarrier概念,常用api,应用场景,实战,更好的理解。

程序猿学社的博客 4228

CyclicBarrier和CountDownLatch的使用

CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行; CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。 对于CountDownLatch来说,重点是“一个线程(多个线程)等待”,而其他的N个线程在完成“某件事情”之后,可以终止,也可以等待。而对于CyclicBarrier,重点是多个线程,在任意一个线程没有完成,所有的线程...

王温暖的博客 545

CountDownLatch和CyclicBarrier的使用和区别

CountDownLatch 标题 countDownLatch是在java1.5被引入,跟它一起被引入的工具类还有 CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。 存在于java.util.cucurrent包下。 概念 countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。 是通过一个计数器来实现的...

magiconion的博客 237

Java并发编程第9讲——CountDownLatch、CyclicBarrier和Semaphore(万字详解)

在JDK的并发包(JUC)里提供了几个非常有用的并发工具类。CountDownLatch、CyclicBarrier和Samaphore工具类提供了一种并发流程控制的手段,这同样也是面试和工作中的一个重要知识点,本文将从它们的定义、常用方法、代码示例及核心源码的分析等几个要点详细介绍一下。

让~学习~成为一种习惯(橡 皮 人の技术博客) 2877

CountDownLatch、CyclicBarrier和Semaphore

前言 学习了aqs源码之后,我觉得很有必要把这三个类再系统的学习一下, 同时记录下学习的过程。如果没有看过aqs独占锁和aqs共享锁的源码,我建议你先去学习aqs。aqs是基础,这三个类只是Doug Lea为了满足多线程编程下各种线程按照需要的场景来运行而写的三个工具类。aqs不懂,学习这三个类也只是走马观花,不得精髓。水平有限,文章中有误的地方也请不吝指正,互相帮助,共同学习。 CountDownLatch CountDownLatch是我在项目中用的最多的一个并发类,现在我更喜欢用Completable

weixin_43727164的博客 493
上一篇: Animation and Graphics partⅡ Property Animation
Appletable
博客等级 码龄14年 0粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值