- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java中CyclicBarrier和CountDownLatch的用法与区别由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
。
CyclicBarrier和CountDownLatch这两个工具都是在java.util.concurrent包下,并且平时很多场景都会使用到。 本文将会对两者进行分析,记录他们的用法和区别.
。
CountDownLatch是一个非常实用的多线程控制工具类,称之为“倒计时器”,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行.
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务.
特点 。
只能一次性使用(不能reset);主线程阻塞;某个线程中断将永远到不了屏障点,所有线程都会一直等待.
。
。
//创建初始化3个线程的线程池 private ExecutorService threadPool = Executors.newFixedThreadPool(3); //保存每个学生的平均成绩 private ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); private CountDownLatch countDownLatch = new CountDownLatch(3); private void count() { for (int i = 0; i < 3; i++) { threadPool.execute(() -> { //计算每个学生的平均成绩,代码略()假设为60~100的随机数 int score = (int) (Math.random() * 40 + 60); try { Thread.sleep(Math.round(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } map.put(Thread.currentThread().getName(), score); System.out.println(Thread.currentThread().getName() + "同学的平均成绩为" + score); countDownLatch.countDown(); }); } this.run(); threadPool.shutdown(); } @Override public void run() { try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } int result = 0; Set<String> set = map.keySet(); for (String s : set) { result += map.get(s); } System.out.println("三人平均成绩为:" + (result / 3) + "分"); } public static void main(String[] args) throws InterruptedException { long now = System.currentTimeMillis(); CyclicBarrier1 cb = new CyclicBarrier1(); cb.count(); Thread.sleep(100); long end = System.currentTimeMillis(); System.out.println(end - now); }
最终输出结果:
其中1194ms证明了会阻塞主线程.
。
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活.
这个屏障之所以用循环修饰,是因为在所有的线程释放彼此之后,这个屏障是可以重新使用的(reset()方法重置屏障点),这一点与CountDownLatch不同.
CyclicBarrier是一种同步机制允许一组线程相互等待,等到所有线程都到达一个屏障点才退出await方法,它没有直接实现AQS而是借助ReentrantLock来实现的同步机制。它是可循环使用的,而CountDownLatch是一次性的,另外它体现的语义也跟CountDownLatch不同,CountDownLatch减少计数到达条件采用的是release方式,而CyclicBarrier走向屏障点(await)采用的是Acquire方式,Acquire是会阻塞的,这也实现了CyclicBarrier的另外一个特点,只要有一个线程中断那么屏障点就被打破,所有线程都将被唤醒(CyclicBarrier自己负责这部分实现,不是由AQS调度的),这样也避免了因为一个线程中断引起永远不能到达屏障点而导致其他线程一直等待。屏障点被打破的CyclicBarrier将不可再使用(会抛出BrokenBarrierException)除非执行reset操作.
。
CyclicBarrier有两个构造函数
CyclicBarrier(int parties) int类型的参数表示有几个线程来参与这个屏障拦截,(拿上面的例子,即有几个人跟团旅游); 。
CyclicBarrier(int parties,Runnable barrierAction) 当所有线程到达一个屏障点时,优先执行barrierAction这个线程.
最重要的一个方法: await();每个线程调用await(),表示我已经到达屏障点,然后当前线程被阻塞.
//创建初始化3个线程的线程池 private ExecutorService threadPool = Executors.newFixedThreadPool(3); //创建3个CyclicBarrier对象,执行完后执行当前类的run方法 private CyclicBarrier cb = new CyclicBarrier(3, this); //保存每个学生的平均成绩 private ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); private void count() { for (int i = 0; i < 3; i++) { threadPool.execute(() -> { //计算每个学生的平均成绩,代码略()假设为60~100的随机数 int score = (int) (Math.random() * 40 + 60); try { Thread.sleep(Math.round(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } map.put(Thread.currentThread().getName(), score); System.out.println(Thread.currentThread().getName() + "同学的平均成绩为" + score); try { //执行完运行await(),等待所有学生平均成绩都计算完毕 cb.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } }); } threadPool.shutdown(); } @Override public void run() { int result = 0; Set<String> set = map.keySet(); for (String s : set) { result += map.get(s); } System.out.println("三人平均成绩为:" + (result / 3) + "分"); } public static void main(String[] args) throws InterruptedException { long now = System.currentTimeMillis(); CyclicBarrier1 cb = new CyclicBarrier1(); cb.count(); Thread.sleep(100); long end = System.currentTimeMillis(); System.out.println(end - now); }
最终输出结果:
显然没有阻塞主线程.
。
我们来从jdk作者设计的目的来看,javadoc是这么描述它们的:
CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. 。
CyclicBarrier: A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. 。
从javadoc的描述可以得出:
CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行; CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。 对于CountDownLatch来说,重点是“一个线程(多个线程)等待”,而其他的N个线程在完成“某件事情”之后,可以终止,也可以等待。而对于CyclicBarrier,重点是多个线程,在任意一个线程没有完成,所有的线程都必须等待.
CountDownLatch是计数器,线程完成一个记录一个,只不过计数不是递增而是递减,而CyclicBarrier更像是一个阀门,需要所有线程都到达,阀门才能打开,然后继续执行.
到此这篇关于Java中CyclicBarrier和CountDownLatch的用法与区别的文章就介绍到这了,更多相关Java CyclicBarrier CountDownLatch内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.csdn.net/zyzzxycj/article/details/90241892 。
最后此篇关于Java中CyclicBarrier和CountDownLatch的用法与区别的文章就讲到这里了,如果你想了解更多关于Java中CyclicBarrier和CountDownLatch的用法与区别的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
介绍 CountDownLatch是一个同步辅助类,它允许一个或多个线程一直等待直到其他线程执行完毕才开始执行。 用给定的计数初始化CountDownLatch,其含义是要被等待执行完的线程个数。 每
在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法: CountDownLatch(int
一 点睛 1 定义 CountDownLatch 是一个同步工具类,可以用来协调多个线程的执行时间。例如,可以让 A 线程在其他线程运行完毕后再执行。也就是说,如果其他线程没有执行完毕,则 A 线程就
以下情况:线程 A 启动线程 B,并应等待线程 B 完成其工作。线程 B 可以启动一个新的线程 C。如果是这样,线程 A 应该等待线程 B 和线程 C。 我可以使用两个 CountDownLatch
有没有办法多次使用唯一的CountDownLatch? 我的意思是在创建 CountDownLatch 实例并设置其计数值后,通过调用该实例上的 countDown() 方法达到 0 后,我们设置一个
大家好,我正在学习教程,我对我尝试应用从教程中获得的知识的一些事情感到好奇。 下面是一个Runner类 package Tutorial2; import java.util.concurrent.C
我有一个希望打印值的代码示例。正如我在 countDownLatch.countDown(); 之后的 run 方法中所想的那样被称为 CountDownLatch 应该达到零并且 main 方法应该
运行每个线程时,为什么即使前一个线程已经调用了 countdown.countDown() 并将 Latch Count 减少了 1,countdown.getCount() 仍总是打印“3”? 我有
我正在处理 CountDownLatch,我需要发送两个 JSON 以按顺序发送。 我想出了这个 CountDownLatch countDownLatch = new CountDownLat
我有一个方法 getNewA() 应该会阻塞,直到其他线程调用 setA(x)。使用 CountDownLatch 是否正确?我注意到存在数据竞争,因为在 gate.await() 解除阻塞后,另一个
有没有办法显式释放 CountDownLatch - 意味着不用 countDown()。 例如:假设我正在等待 100 个线程来执行 countDown(),但是如果某件事失败了,我想释放这个闩锁而
等待/通知和锁定/条件等并发管理机制似乎受到spurious wakeups的影响.开发人员通过重新检查条件是否确实发生了变化来应对这些意外唤醒。 就 CountDownLatch 而言,虚假唤醒是一
对于某些并发编程,我可以使用 Java 的 CountDownLatch概念。是否有 C++11 的等效项,或者该概念在 C++ 中称为什么? 我想要的是在计数达到零时调用一个函数。 如果还没有,我会
我有一个方法,它从 Firebase 存储加载图像。它在后台线程中调用,我需要阻止它,直到加载图像(以避免回调 hell )。这是代码(在 Kotlin 中) override fun fromNet
我正在使用 CountDownLatch在两个线程之间同步初始化过程,我想知道如何正确处理 InterruptedException它可能会抛出。 我最初写的代码是这样的: private C
使用有什么好处 java.util.concurrent.CountdownLatch 而不是 java.util.concurrent.Semaphore ? 据我所知,以下片段几乎是等价的: 1.
关注 王有志 ,一个分享硬核Java技术的互金摸鱼侠 欢迎你加入 Java人的提桶跑路群 : 共同富裕的Java人 今天我们来聊一聊AQS家族中的另一个重要成员Coun
功能简介 闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态【CPJ 3.4.2】。闭锁的作用相当于一扇门∶ 在闭锁到达结束状态之前,这扇门一直是关闭的,并且没有任何线程能通过,当到达
一入王者深似海,从此对象是路人。 哈喽观众老爷们你们好,在下战神吕布字奉先,今天给大家来一部吕布的教学视频! 咳咳,不对。大家好,我是磊哥,今天给大家来一篇 CountDownLatch 的
本章节我们来讨论下 java.util.concurrent.CountDownLatch 这个类,顺带演示下如何在一些实际例子中使用它。 CountDownLatch 类的作用呢? 怎么说呢? 简
我是一名优秀的程序员,十分优秀!