Semaphore,CountDownLatch,CyclicBarrier

【JUC】循环屏障CyclicBarrier详解 jdk中提供了许多的并发工具类,大家可能比较熟悉的有,主要用来阻塞一个线程运行,直到其他线程运行完毕。而jdk还有一个功能类似并发工具类,你知道它的作用吗?和有什么区别呢?对于CountDownLatch不了解的可以参考# CountDownLatch源码硬核解析,循环屏障,用来进行线程协作,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,会触发自己运行,运行完后,屏障又会开门,所有被屏障拦截的线程又可以继续运行。所以是可以重用的。 阅读详情

1、atomic包的原理及分析

概论:

  • CountDownLatch是一个计数器闭锁,主要的功能就是通过await()方法来阻塞住当前线程,然后等待计数器减少到0了,再唤起这些线程继续执行。 这个类里主要有两个方法,一个是向下减计数器的方法countdown();
  • Semaphore与CountDownLatch相似,不同的地方在于Semaphore的值被获取到后是可以释放的,并不像CountDownLatch那样一直减到底。它也被更多地用来限制流量,类似阀门的 功能。如果限定某些资源最多有N个线程可以访问,那么超过N个主不允许再有线程来访问,同时当现有线程结束后,就会释放,然后允许新的线程进来。有点类似于锁的lock与 unlock过程。相对来说他也有两个主要的方法:
    用于获取权限的acquire(),其底层实现与CountDownLatch.countdown()类似;用于释放权限的release(),其底层实现与acquire()是一个互逆的过程。
  • CyclicBarrier是用来一个关卡来阻挡住所有线程,等所有线程全部执行到关卡处时,再统一执行下一步操作,它里面最重要的方法是await()方法

    1. Semaphore
  • 一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动;
  • Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。例如,下面的类使用信号量控制对内容池的访问:

         class Pool {
           private static final int MAX_AVAILABLE = 100;
           private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
    
           public Object getItem() throws InterruptedException {
             available.acquire();
             return getNextAvailableItem();
           }
    
           public void putItem(Object x) {
             if (markAsUnused(x))
               available.release();
           }
    
           // Not a particularly efficient data structure; just for demo
    
           protected Object[] items = ... whatever kinds of items being managed
           protected boolean[] used = new boolean[MAX_AVAILABLE];
    
           protected synchronized Object getNextAvailableItem() {
             for (int i = 0; i < MAX_AVAILABLE; ++i) {
               if (!used[i]) {
                  used[i] = true;
                  return items[i];
               }
             }
             return null; // not reached
           }
    
           protected synchronized boolean markAsUnused(Object item) {
             for (int i = 0; i < MAX_AVAILABLE; ++i) {
               if (item == items[i]) {
                  if (used[i]) {
                    used[i] = false;
                    return true;
                  } else
                    return false;
               }
             }
             return false;
           }
    
         }
    
  • 获得一项前,每个线程必须从信号量获取许可,从而保证可以使用该项。该线程结束后,将项返回到池中并将许可返回到该信号量,从而允许其他线程获取该项。注意,调用 acquire() 时无法保持同步锁,因为这会阻止将项返回到池中。信号量封装所需的同步,以限制对池的访问,这同维持该池本身一致性所需的同步是分开的。
  • 将信号量初始化为 1,使得它在使用时最多只有一个可用的许可,从而可用作一个相互排斥的锁。这通常也称为二进制信号量,因为它只能有两种状态:一个可用的许可,或零个可用的许可。按此方式使用时,二进制信号量具有某种属性(与很多 Lock 实现不同),即可以由线程释放“锁”,而不是由所有者(因为信号量没有所有权的概念)。在某些专门的上下文(如死锁恢复)中这会很有用。
  • 此类的构造方法可选地接受一个公平 参数。当设置为 false 时,此类不对线程获取许可的顺序做任何保证。特别地,闯入 是允许的,也就是说可以在已经等待的线程前为调用 acquire() 的线程分配一个许可,从逻辑上说,就是新线程将自己置于等待线程队列的头部。当公平设置为 true 时,信号量保证对于任何调用获取方法的线程而言,都按照处理它们调用这些方法的顺序(即先进先出;FIFO)来选择线程、获得许可。注意,FIFO 排序必然应用到这些方法内的指定内部执行点。所以,可能某个线程先于另一个线程调用了 acquire,但是却在该线程之后到达排序点,并且从方法返回时也类似。还要注意,非同步的 tryAcquire 方法不使用公平设置,而是使用任意可用的许可。
  • 通常,应该将用于控制资源访问的信号量初始化为公平的,以确保所有线程都可访问资源。为其他的种类的同步控制使用信号量时,非公平排序的吞吐量优势通常要比公平考虑更为重要。

    1. CountDownLatch
  • 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
  • 用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。
  • CountDownLatch 是一个通用同步工具,它有很多用途。将计数 1 初始化的 CountDownLatch 用作一个简单的开/关锁存器,或入口:在通过调用 countDown() 的线程打开入口前,所有调用 await 的线程都一直在入口处等待。用 N 初始化的 CountDownLatch 可以使一个线程在 N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 次之前一直等待。
  • CountDownLatch 的一个有用特性是,它不要求调用 countDown 方法的线程等到计数到达零时才继续,而在所有线程都能通过之前,它只是阻止任何线程继续通过一个 await。

  • 示例用法: 下面给出了两个类,其中一组 worker 线程使用了两个倒计数锁存器:
    第一个类是一个启动信号,在 driver 为继续执行 worker 做好准备之前,它会阻止所有的 worker 继续执行。
    第二个类是一个完成信号,它允许 driver 在完成所有 worker 之前一直等待。

        class Driver { // ...
           void main() throws InterruptedException {
             CountDownLatch startSignal = new CountDownLatch(1);
             CountDownLatch doneSignal = new CountDownLatch(N);
    
             for (int i = 0; i < N; ++i) // create and start threads
               new Thread(new Worker(startSignal, doneSignal)).start();
    
             doSomethingElse();            // don't let run yet
             startSignal.countDown();      // let all threads proceed
             doSomethingElse();
             doneSignal.await();           // wait for all to finish
           }
         }
    
         class Worker implements Runnable {
           private final CountDownLatch startSignal;
           private final CountDownLatch doneSignal;
           Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
              this.startSignal = startSignal;
              this.doneSignal = doneSignal;
           }
           public void run() {
              try {
                startSignal.await();
                doWork();
                doneSignal.countDown();
        } catch (InterruptedException ex) {} // return;
           }
    
           void doWork() { ... }
         }
    
    1. CyclicBarrier
      • 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
  • CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。
  • 示例用法:下面是一个在并行分解设计中使用 barrier 的例子:

         class Solver {
           final int N;
           final float[][] data;
           final CyclicBarrier barrier;
    
           class Worker implements Runnable {
             int myRow;
             Worker(int row) { myRow = row; }
             public void run() {
               while (!done()) {
                 processRow(myRow);
    
                 try {
                   barrier.await(); 
                 } catch (InterruptedException ex) { 
        return; 
                 } catch (BrokenBarrierException ex) { 
        return; 
                 }
               }
             }
           }
    
           public Solver(float[][] matrix) {
             data = matrix;
             N = matrix.length;
             barrier = new CyclicBarrier(N, 
                                         new Runnable() {
                                           public void run() { 
                                             mergeRows(...); 
                                           }
                                         });
             for (int i = 0; i < N; ++i) 
               new Thread(new Worker(i)).start();
    
             waitUntilDone();
           }
         }
    

    在这个例子中,每个 worker 线程处理矩阵的一行,在处理完所有的行之前,该线程将一直在屏障处等待。处理完所有的行之后,将执行所提供的 Runnable 屏障操作,并合并这些行。如果合并者确定已经找到了一个解决方案,那么 done() 将返回 true,所有的 worker 线程都将终止。

  • 如果屏障操作在执行时不依赖于正挂起的线程,则线程组中的任何线程在获得释放时都能执行该操作。为方便此操作,每次调用 await() 都将返回能到达屏障处的线程的索引。然后,您可以选择哪个线程应该执行屏障操作,例如:
    if (barrier.await() == 0) {
    // log the completion of this iteration
    }
    对于失败的同步尝试,CyclicBarrier 使用了一种要么全部要么全不 (all-or-none) 的破坏模式:如果因为中断、失败或者超时等原因,导致线程过早地离开了屏障点,那么在该屏障点等待的其他所有线程也将通过 BrokenBarrierException(如果它们几乎同时被中断,则用 InterruptedException)以反常的方式离开。

  • 内存一致性效果:线程中调用 await() 之前的操作 happen-before 那些是屏障操作的一部份的操作,后者依次 happen-before 紧跟在从另一个线程中对应 await() 成功返回的操作。

【高并发】JUC中的循环栅栏CyclicBarrier的6种使用场景 JUC中的循环栅栏CyclicBarrier的6种使用场景。 CyclicBarrier通常称为循环屏障。它和CountDownLatch很相似,都可以使线程先等待然后再执行。不过CountDownLatch是使一批线程等待另一批线程执行完后再执行;而CyclicBarrier只是使等待的线程达到一定数目后再让它们继续执行。故而CyclicBarrier内部也有一个计数器,计数器的初始值在创建对象时通过构造参数指定,如下所示: 。除此之外,CyclicB 阅读详情

相关推荐

CountDownLatch、CyclicBarrier、Semaphore源码解析

CountDownLatch 1 前言 CountDownLatch是一种同步辅助工具类,它允许一个或多个线程等待,直到在其他线程中执行的一组操作完成为止。(源码分析基于JDK1.8)CountDownLatch需要用给定的闩锁计数count初始化。await方法使当前线程阻塞(每执行一次countDown方法就将闩锁计数减1),直到闩锁计数达到零时(所有因此阻塞等待的线程都)才会被唤醒。CountDownLatch是一次性使用的同步工具,闩锁计数无法重置,如果需要重置计数,可能使用CyclicBar.

FREEDOM 983

CyclicBarrier 使用案例详解

CyclicBarrier 概念: CyclicBarrier 字面意思是环栅栏,是 JUC 下的一个并发工具,跟 CountDownLatch 很相似,都可以使线程先等待然后再执行,但是它的功能比 CountDownLatch 更加复杂和强大, CountDownLatch 是一个或者多个线程等待另外一批线程执行完毕后,在接着执行,而 CyclicBarrier 是等待一批线程到达某个状态之后再同时开始执行,回环的意思是当所有的线程被释放后,CyclicBarrier 可以被重启,也就是可以重复使用

weixin_42118323的博客 4586

17【Protues单片机仿真】基于51单片机的太阳能智能谷物翻晒机器人

基于51单片机,避障,低于50CM报警,LED灯亮起,自动翻晒用光敏电阻,光照强度大,电机转动,相当于翻晒粮食,远程控制用按键代替,按下去电机就转动,相当于翻晒粮食,然后光照强度和超声波的距离都在LCD1602显示屏显示出来。

weixin_70360261的博客 1448

简述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

DJI MobileSDK运行实例代码教程(保姆级)坑踩完了

其中比较重要的是PackageName也就是我们应用的包名,在这里我们可以直接使用官方文档中的包名,com.dji.ImportSDKDemo,appname为:ImportSDKDemo,其他的可以随意。在C盘中根据路径先找到 “用户/admin/.gradle”下的.gradle文件夹,然后依次打开wrapper/dists文件夹,找到我们刚刚要下载的gradle版本名的文件夹。在Androidstudio中打开,选在打开项目选择文件下载后的保存路径(解压之后的),在打开项目后会自动下载gradle。

k1121568的博客 2863

OpenCV学习笔记(25)基于MFC和OpenCV的摄像机定标与立体匹配测试程序(20140505更新)

最近整理了一下这两年一直在用的摄像机定标与立体匹配测试程序,将代码进行了重构,界面也做了调整,分享出来方便有需要的朋友使用。当然我的编程能力有限,程序可能还有各种bug,请大家多多包涵。相关问题欢迎留言或email联系讨论,谢谢! ==================================================================================源码

晨宇思远 5万+

CyclicBarrier 用法详解

CyclicBarrier 用法详解 CyclicBarrier使用场景 用于协调多个线程同步执行操作的场合,所有线程等待完成,然后一起做事情( 相互之间都准备好,然后一起做事情 ) 例如百米赛跑,必须等待所有运动员都准备好了,才能比赛。 运动员准备好,裁判也准备好,才能开始正式比赛。 CyclicBarrier cyclicBarrier = new CyclicBarrier(3); new Thread(() -> { try {

. 8953

机器视觉/将HIK海康面阵相机连接Halcon软件

本文简述了如何将海康面阵相机连接到Halcon软件中进行实时取图的过程。

Dahe.qu 4866

【Java并发】辅助类CountDownLatch、CyclicBarrier、Semaphore

本文总结了JUC常用三大辅助类CountDownLatch、CyclicBarrier、Semaphore的使用方法(含示例代码和方法解析)。

hrh的博客 3224

高级数据库--作业及答案

中科大金培权老师的高级数据库课程作业及答案

一杯水果茶!足矣~ 1658

Python爬虫博客:如何抓取时事新闻信息 —— 从各大新闻网站获取实时新闻数据

发送请求:向目标新闻网站发送 HTTP 请求,获取网页内容。解析网页:使用解析库(如)从网页中提取新闻标题、摘要、内容、发布时间等。绕过反爬虫机制:使用代理、设置请求头、模拟浏览器行为等策略绕过反爬虫技术。数据存储与清洗:将抓取的数据保存到本地文件或数据库中,并进行清洗,确保数据的可用性。在抓取过程中,我们还会面对很多实际问题,比如反爬虫技术、分页抓取、动态加载的内容等。接下来,我们将逐步介绍如何使用不同技术抓取静态和动态网页,并对抓取的内容进行处理。Scrapy。

2201_76125261的博客 2135

CountDownLatch、CyclicBarrier 和 Semaphore

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

程序员Forlan的博客 1803

Python 爬虫实战:爬取今日头条文章与阅读量数据

本文详细介绍了基于Python爬取今日头条文章与阅读量数据的完整方案。通过分析今日头条API接口,采用Requests+正则表达式技术实现数据抓取,重点解决加密参数构造、请求头模拟、反爬规避等核心问题。文章包含文章列表获取、详情数据提取、互动数据采集等完整流程,并提供数据存储与基础分析方法。同时强调合规使用爬虫技术,控制爬取频率,避免干扰平台运营。该方案可为内容传播分析、用户兴趣研究提供数据支持,但需注意接口参数更新和反爬机制变化,适时调整代码实现。

2503_91057718的博客 2519

CountDownLatch、CyclicBarrier、semaphore

CountDownLatch中调用await方法线程需要等待所有调用countDown方法的线程执行,这就很适合一个业务需要一些准备条件,等准备条件准备好之后再继续执行,如果一些复杂的聚合查询,还有一些类似于广播消息的功能。

星坠竹空 1582

Plecs电力电子仿真专业教程-第一季 补充课程 Plecs的安装教程与软件下载

PLECS4.1.64免安装版本–点我下载 Plecs.Standalone-3.7.2版本--关注加私信给我可以提供下载链接 补充课程 Plecs的安装教程与软件下载 详细介绍Plecs软件的安装过程

1万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

CountDownLatch、CyclicBarrier和Semaphore

CountDownLatch、CyclicBarrier和Semaphore CountDownLatch: 计数器,某个线程等待N个线程执行完毕后再继续执行,N就是对应的计数,每个执行完毕就减一,直到所有完成。可以看作是1个等多个。 常用方法: public CountDownLatch(int count) { }; public void await() throws Interrup...

每天进步一点点 1774

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

深入解析 CountDownLatch、Semaphore 和CyclicBarrier

特性Semaphore核心目标等待一组操作完成控制资源并发访问多线程协同到达屏障点重用性否(一次性)是(许可可释放)是(自动或手动重置)底层实现AQS 共享锁AQS 共享锁适用场景主从协作(一等多)资源池化/限流(多对多)多线程分阶段协作(多对多)异常处理无特殊异常需处理 InterruptedException需处理 BrokenBarrierException性能影响低(仅计数器操作)中等(CAS 竞争)高(锁竞争 + 条件变量)

fjkxyl的博客 1077

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

CountDownLatch、Semaphore、CyclicBarrier

同步一批线程的行为 CountDownLatch、Semaphore、CyclicBarrier

一张小羊毛的博客 3345

CountDownLatch、CyclicBarrier、Semaphore、Exchanger详解

CountDownLatch CountDownLatch 允许一个或多个线程等待其他线程完成操作。 假如有这样一个需求:我们需要解析一个Excel里多个sheet的数据,此时可以考虑使用多 线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完之后,程序需要提示解析完 成。在这个需求中,要实现主线程等待所有线程完成sheet的解析操作,最简单的做法是使用 join()方法: public class JoinCountDownLatchTest { public static v

7me 6287

CountDownLatch、CyclicBarrier与Semaphore 核心技术解析

文章深入分析了CountDownLatch、CyclicBarrier和Semaphore三大并发工具的核心实现。CountDownLatch基于AQS共享模式实现一次性计数器同步,通过state字段存储计数值,在计数归零时唤醒所有等待线程。CyclicBarrier采用ReentrantLock+Condition实现可重复使用的栅栏同步,支持周期性重置。Semaphore同样基于AQS,通过state管理许可证数量,提供公平与非公平两种获取策略。

lifallen的博客 1175

CountDownLatch、CyclicBarrier、Semaphore

一、CountDownLatch 直接上代码看效果 /* * Copyright (C), 2013-2019, 天津大海云科技有限公司 */ import java.util.concurrent.CountDownLatch; /** * @author yangjikang * @date 2019/6/17 14:05 * @description CountDownLat...

weixin_39827145的博客 166

Semaphore、CountdownLatch、CyclicBarrier详解

文章目录1.Semaphore1.1 基本使用1.2 Semaphore原理-图解流程1.3 Semaphore原理-源码分析2.CountdownLatch3.CyclicBarrier 1.Semaphore 信号量,用来限制能同时访问共享资源的线程上限。 1.1 基本使用 /** * @ClassName SemaphoreTest * @author: shouanzh * @Description 信号量,用来限制能同时访问共享资源的线程上限。 * @date 2022/3/20 11:3

张大安的博客 1084

Semaphore、CountDownLatch、CyclicBarrier原理

对于AQS的原理和ReentrantLock原理不熟悉的小伙伴可以参考上篇文章(并发编程之AQS原理及其ReentrantLock原理),这篇文章我们再继续深入看下AQS 一、Semaphore底层实现(author:Doug Lea) //信号量 共享锁 Semaphore windows = new Semaphore(3); for(int i=0; i<5; i++) { Thread t = new Thread((

Zong__Zong的博客 307

CountDownLatch、CyclicBarrier、Semaphore详解

CountDownLatch CountDownLatch概念 CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。 CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表...

方亚军的博客 1887

简析CountDownLatch、CyclicBarrier、Semaphore

一、CountDownLatch 1、定义 用来协调线程间的同步,起到线程之间的通信作用的工具类。 它能够使一个线程再等待一些线程完成各自工作后,再继续执行。使用一个计数器实现,计数器初始值为线程的数量,当每一个线程完成自己任务后,计数器的值会减1,当计数器的值为0时,表示所有的线程都完成了任务,然后CountDownLatch上等待的线程就可以恢复执行任务。 2、应用场景 某一个线程再开始运行前等待n个线程执行完毕,如启动一个服务时,主线程需要等待多个组件加载完毕,之后再执行...

heyi12345的专栏 544

CountDownLatch/CyclicBarrier/Semaphore

Zookeeper与Kafka集群搭建CountDownLatchCyclicBarrierCountDownLatch 和 CyclicBarrier 的区别Semaphore CountDownLatch 闭锁,在完成某些运算是,只有其他所有线程的运算全部完成,当前运算才继续执行 让一些线程阻塞,直到另一些线程完成一系列操作后才被唤醒 CountDownLatch主要有两种方法,当一个或多个线...

wuzhenwei0419的博客 200
上一篇: 锁的一些基本概念
下一篇: HTTP
iQuester
博客等级 码龄11年 22粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值