范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

CountDownLatch,CyclicBarrier,Semaphore的使用及底层实现

  今天我们就详细介绍一下JUC的一些常用同步工具类,减少计数(CountDownLatch),循环栅栏(CyclicBarrier),信号灯(Semaphore)的使用和区别。  CountDownLatch
  作用 :就是一个或者多个线程在开始执行操作之前,必须要等到其他线程执行完成才可以执行。
  类的构造方法  CountDownLatch(int count) 构造一个用给定计数初始化的值。 public CountDownLatch(int count) {         if (count < 0) throw new IllegalArgumentException("count < 0");         this.sync = new Sync(count);     }
  核心方法
  countDown() 递减锁存器的计数,如果计数达到零,将释放所有等待的线程 public void countDown() {         sync.releaseShared(1); }
  await()  使当前线程在锁存器倒计数至零之前一直处于等待。 public void await() throws InterruptedException {         sync.acquireSharedInterruptibly(1); }
  当线程调用 await()方法时,就会阻塞当前线程。当线程调用一次countDown()方法时,count 就会减一,直到当count  的值等于0时候,被阻塞的线程才可以继续执行。
  现在我们用一个生活中的例子说明:学生时代,当我们在考试的时候,监考老师必须等到所有的学生交完卷子才可以离开,此时监考老师就相当于等待线程,而学生就好比是执行的线程。
  我们用代码实现这个案例:
  参加考试的学生10个, main线程就相当于监考老师  public class CountDownLatchDemo {         private static CountDownLatch countDownLatch = new CountDownLatch(10);     public static void main(String[] args) throws InterruptedException {         for (int i = 1; i <= 10; i++) {             new Thread(new Runnable() {                 @Override                 public void run() {                     System.out.println(Thread.currentThread().getName()+"	 学生交卷:");                     // 减一                     countDownLatch.countDown();                 }             },String.valueOf(i)).start();         }         // 等待         countDownLatch.await();         System.out.println(Thread.currentThread().getName()+"	 监考老师离开教室");     } }
  底层实现原理
  从源码我们不难发现 CountDownLatch 是基于AQS实现的,当我们在构建CountDownLatch 对象时,传入的值其实就会赋值给 AQS 的关键变量state,执行**countDown()方法时,其实就是利用CAS 将state 减一,执行 await()**方法时,其实就是判断state是否为0,不为0则加入到队列中,将该线程阻塞掉(除了头节点),因为头节点会一直自旋等待state为0,当state为0时,头节点把剩余的在队列中阻塞的节点也一并唤醒。 CyclicBarrier
  作用:N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
  常用的构造方法有:  CyclicBarrier(int parties,Runnable barrierAction) 创建一个新的CyclicBarrier,它将在给定数量的线程处于等待状态时启动,并在启动barrier时执行给定的屏障操作,该操作由最后一个进入barrier的线程操作  public CyclicBarrier(int parties, Runnable barrierAction) {         if (parties <= 0) throw new IllegalArgumentException();         this.parties = parties;         this.count = parties;         this.barrierCommand = barrierAction; }
  核心方法
  await() 在所有的参与者都已经在此barrier上调用await方法之前一直等待 public int await() throws InterruptedException, BrokenBarrierException {         try {             return dowait(false, 0L);         } catch (TimeoutException toe) {             throw new Error(toe); // cannot happen         }     }
  生活中的例子:在打王者的时候,在开局前所有人都必须要加载到100%才可以进入。否则所有玩家都相互等待。  public class CyclicBarrierDemo {      public static void main(String[] args) {         CyclicBarrier cyclicBarrier =new CyclicBarrier(5, () -> System.out.println("游戏开始"));          for (int i = 1; i <=5 ; i++) {             int finalI = i;             new Thread(new Runnable() {                 @Override                 public void run() {                     System.out.println("第"+ finalI +"进入游戏");                     try {                         cyclicBarrier.await();                     } catch (InterruptedException e) {                         e.printStackTrace();                     } catch (BrokenBarrierException e) {                         e.printStackTrace();                     }                 }             },String.valueOf(i)).start();         }     } }
  总结:CyclicBarrier 的构造方法第一个参数是目标障碍数,每次执行 CyclicBarrier 一次障碍数会加一,如果达到了目标障碍数,才会执行 await()之后方法。
  底层实现原理
  从源码不难发现的是,它没有像 CountDownLatch 和ReentrantLock 使用AQS的state变量,而CyclicBarrier 是直接借助ReentrantLock 加上Condition  等待唤醒的功能 进而实现的。
  在构建 CyclicBarrier 时,传入的值会赋值给CyclicBarrier 内部维护count 变量,也会赋值给parties 变量,每次调用await()方法时,会将count 减一 ,操作count值是直接使用ReentrantLock 来保证线程安全性。如果count不为0,则添加Condition 队列中,如果count等于0时,则把节点从Condition 队列添加至AQS的队列中进行全部唤醒,并且将parties的值重新赋值为count的值。 Semaphore
  信号量,用来控制同一时间,资源可被访问的线程数量,一般应用场景流量的控制。
  构造方法  Semaphore(int permits) 创建具有给定的许可数和非公平的公平设置的Semapore public Semaphore(int permits) {         sync = new NonfairSync(permits); }
  核心方法  acquire() 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断,release() 释放一个许可,将其返回给信号量,设置许可数量Semaphore semaphore = new Semaphore(3) ,一般acquire() 都会抛出异常,release 在finally 中执行。 public void acquire() throws InterruptedException {         sync.acquireSharedInterruptibly(1); }public void release() {         sync.releaseShared(1); }
  举例说明,6辆强站三个停车位。  public class SemaphoreDemo {      public static void main(String[] args) {         // 模拟资源类,有3个空车位         Semaphore semaphore = new Semaphore(3);         for (int i = 1; i <=6 ; i++) {             new Thread(() -> {                 try {                     semaphore.acquire();                     System.out.println(Thread.currentThread().getName()+"	 抢到了车位");                     TimeUnit.SECONDS.sleep(3);                 } catch (InterruptedException e) {                     e.printStackTrace();                 }finally {                     semaphore.release();                 }                 System.out.println(Thread.currentThread().getName()+"	 离开了车位");                 semaphore.release();         },String.valueOf(i)).start();         }     } }
  Semaphore 底层实现是基于AQS实现的类似于 CountDownLatch  总结
  CountDownLatch ,Semaphore 都是基于AQS实现。
  CountDownLatch 是一个线程等待其他线程,CyclicBarrier 是线程之间相互等待。
  CountDownLatch 会将构造CountDownLatch 的入参传递至state,**countDown()就是在利用CAS将state减一, await()**实际就是让头节点一直在等待state为0时,释放所有等待的线程。
  CyclicBarrier 则利用ReentrantLock 和Condition ,自身维护了count和parties变量。每次调用await将count减一,并将线程加入到Condition 队列上。等到count为0时,则将Condition 队列的节点移交至AQS队列,并全部释放。

宿迁寻亲六旬老人被救助数日,疑似名叫吴超用,高1米68受助者姓名吴超用(疑似)受助者性别男受助者年龄约65岁寻亲编号23012受助原因其它受助者特征疑似名叫吴超用,高1米68,重70公斤受助时间20230114受助地点江苏宿迁市宿豫区农村四大歪风要严打了!中央一号文件有要求,全都整治!如今农村已经有了很大的变化,许多的城里人在看到之后也无比的羡慕,每当周末或者逢年过节的时候,在农村的马路上都会堵车堵到不行,一时间,原本空荡荡的地方都会变成一个大型停车场,平时冷冷脑供血不足中医分症有效治疗头晕迷糊,严重时恶心呕吐,多年以来反反复复,真的没有什么办法吗?这篇文章就给大家分析,什么症状该怎么治疗,通过中医分症来精准治疗。导致脑供血不足的原因有很多,比如代谢综合征低血压心购买开学礼物,首选好听好看的华为FreeBuds系列耳机!在超长寒假之后,学生陆续迎来开学。开学季就要添新装备,无论是送自己还是送朋友,华为FreeBuds系列TWS耳机都可以成为首选!华为FreeBuds系列耳机在降噪音质等方面,都有领阿涅利辞去尤文主席因为我被调查,不希望俱乐部因为我背上包袱直播吧2月25日讯前尤文图斯主席阿涅利日前接受了荷兰电讯报采访,并谈到自己被禁足2年卸任尤文图斯主席一职的话题。被禁止参加足球活动2年这次处罚是意大利足协在研究了司法部的调查后对我荤素搭配,营养均衡,减脂下饭菜这样做,上桌就秒光!以前外出吃饭总会点上一盘木须肉,有肉有菜很下饭。木耳鸡蛋肉这三样食材是必备的。滑嫩的肉片,香软的鸡蛋,搭配脆滑的木耳和胡萝卜,还有清爽的黄瓜,简直不要太好吃了!家里正好还有这些食材周末家庭聚餐,八道硬菜别错过,酱汁浓郁超下饭,端上桌人人称赞大家好这里是香姐说美食,每天分享好吃的家常菜。不知不觉又一个星期即将过去,今天是星期五,也是我们上班族常说的小周末,过了这一天就到我们天天盼的周末了。忙碌了一周的上班族,在难得的周春天干饭,必备七道下饭菜,荤素搭配营养高,大人小孩都爱吃大家好这里是香姐说美食,每天分享好吃的家常菜。寒冷的冬天过去了,春天悄悄地来了,春回大地万物复苏,一派生机勃勃的景象。在欣赏春天美景的同时,别忘了春天也是一个调理身体的好季节,建议体内有结节的人,4种发物尽量少吃导语随着生活水平的不断提高,人们的健康意识越来越强,许多人已经养成了定期体检的习惯,虽然一些体检项目的价格并不便宜,但定期体检可以发现体内隐藏的症状并采取预防措施,这对预防疾病有很中国在没有引入阿拉伯数字前,古人怎么书写算式解答数学问题?汉字里表示数字的常用字有一二三四五六七八九十百千万亿兆。对应的大写分别是零壹贰叁肆伍陆柒捌玖拾佰仟萬億兆。比兆更大的数字单位有京垓秭穰沟涧正载极,不过,它们并不常用。当然,汉字里还古人的生活条件有多苦?看完你还想穿越吗?随着近几年穿越题材的影视剧小说的爆火,许多观众朋友们心中也萌生了穿越到古代,利用现代人智慧出人头地的想法。但电视剧毕竟是电视剧,总是会将更好的一面呈现给观众看。不同于科技支撑下的现
一个家庭最好的规矩,离不开这四点!(说得真好)活在这个世上,几乎每个人都想要幸福快乐地生活,想日子过得富裕,一家人其乐融融地在一起,当然想是一回事,能不能实现则是另一回事。很多人以为家庭中只要有钱了就会幸福,实际上这是片面的,人间清醒傅首尔金句合集当30岁还在为10块打车费纠结,下雨天没人送伞,下班再晚没人询问,你就会明白,爱不爱有什么用,谋生才是体面当孩子有100颗糖时,你怎么会介意分享,可当他只有两颗糖,你又凭什么叫他大少动情,多挣钱阅读本文前,点击上方卡片一键关注Episode02366去爱那个拿真金白银对你好的人爱是行动不是光靠嘴爱这个东西如果不能锦上添花不能雪中送碳真的没必要来苦练七十二变才能笑对八十一难内心的黑狗达我在岛屿读书三十多年过去了,我突然回想起来在小镇的童年生活。大抵那个九十年代的小镇,我们所经历的生活,都是整个时代的缩影。如今的妈妈,依旧会用祈求神灵的方式,来对待我的孩子。我默不简谈我的同学李杰作为一名成年人,内心已经没有了年少时的脆弱。幸运的是,校园环境可以包容少年的脆弱,不幸的是,目前校园里还存在着多多少少的校园欺凌问题。大部分人都会对被欺负者产生同情之心,对施暴者深卫浴匠心青春力量丨2022中国民族卫浴发展峰会在佛山盛大召开11月9日,卫浴匠心青春力量2022中国民族卫浴发展峰会在广东佛山盛大召开。来自政府行业协会企业家和媒体在内的500余名业内人士同聚一堂,共话卫浴行业新机遇见证卫浴行业大国品牌,着新研究发现银河系中最古老行星碎片环球网科技综合报道11月8日消息,据外媒报道,由英国华威大学领导的天文学家们团队发现一颗距离地球90光年的微弱白矮星及其轨道行星系统的残骸,它们已有超过100亿年的历史。在这项研究台积电突然发话,不能出货就中企背锅?芯片专家咎由自取在市场规则下,台积电选择了遵从,所以失去了第二大客户订单,也因此对美国客户产生订单依赖。美国一次次修改规则,台积电的态度也非常明确,把美国客户订单放在了第一位。而台积电再次摆正了芯中国航天新纪录!西昌卫星发射中心完成第200次发射任务11月12日上午,我国在文昌航天发射场使用长征七号运载火箭,成功发射天舟五号货运飞船。这是文昌航天发射场所在的西昌卫星发射中心完成的第200次发射任务,该中心也成为我国首个突破206连胜!NBA夺冠热门大爆发,即将登顶联盟第1,头号巨星恐怖升级北京时间11月13日,NBA常规赛凯尔特人117108击败活塞,他们悄无声息地拿下了6连胜,距离登顶联盟第一已经只剩下了0。5个胜场。而在多项数据上,凯尔特人也领衔全联盟30支队伍竞赛题6235。逐层排序二叉树所需的最少操作数目头条创作挑战赛题目给你一个值互不相同的二叉树的根节点root。在一步操作中,你可以选择同一层上任意两个节点,交换这两个节点的值。返回每一层按严格递增顺序排序所需的最少操作数目。节点