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

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队列,并全部释放。

NBA共有17位球星拥有私人飞机,谁的飞机价格最昂贵?人靠衣装马靠鞍,在2004年麦迪首次购买私人飞机后,这项交通工具也就成为了NBA领域里的弄潮儿,如今我们已知的就有17位球星购买过私人飞机,其中飞机价值过千万的就有八位之多,下面我不务正业?不误正业国内网络平台又炸啦!根据新华社报道,红牛BCOne霹雳舞赛事主办方9月16日在社交媒体上宣布,中国霹雳舞选手刘清漪获全球总决赛外卡,成为首位被邀请直通该赛事全球总决赛的中国女子选手最后一舞!费德勒退役泪洒现场,纳达尔致歉,4大满贯官方祝福近日,网球拉沃尔杯得到了很多球迷的关注,原因在于这项赛事将成为费德勒这位伟大巨星的最后一舞,费德勒在球员生涯中取得了无数的荣誉,他拿到了20个大满贯的成绩,曾经长达数年霸占着世界第恭喜国米!张康阳拒绝跑路,效仿许家印,坚守蓝黑军团,剑指欧冠近日,有关于张康阳将出售国米的新闻不绝于耳,作为苏宁集团的公子,张康阳主管体育业务,在收购蓝黑军团后,张康阳陆续为球队注资5亿欧元,让国米重新登上了意甲冠军的宝座。不过,随着大环境全民体育意甲巴黎大区联赛主席涉嫌性骚扰16岁裁判,现已免职仅仅五分钟后,这是一个很好的组合莱昂内尔梅西内马尔派人巴黎圣日耳曼在轻松战胜里昂的路上。也不要让10的比分欺骗了你巴黎圣日耳曼队稳稳地坐在驾驶座上,本可以进更多的球。他们已经看起来了解一下速度滑冰和短道速滑运动的发展历史及二者的区别说起速度滑冰和短道速滑,许多不太了解冬奥会项目的观众,很容易把二者混为一谈。比如2014年张虹夺得金牌后,媒体报道这是中国的首枚速度滑冰金牌,笔者有位朋友就和中国首枚短道速滑金牌分今日分享荷兰vs比利时今天继续聊球,欧国联荷兰主场迎战比利时。提起荷兰不禁让我想起2010年的南非世界杯决赛,荷兰遗憾获得亚军,小飞侠罗本单刀直入被圣卡西用脚挡出,距离大力神杯仅一步之遥。3年1850万!一夜5笔签约骑士大手笔,CJ续约鹈鹕!太阳再签悍将相比较暗流涌动的交易市场,休赛期自由市场上的抢人大战和军备竞赛,可以说向来不乏看点。而仅仅一夜,自由市场又传来了5笔签约消息,这其中,骑士大手笔,CJ续约鹈鹕,太阳再签悍将!签约1世乒赛上,中国男团被剃光头,05惨遭横扫,技术落后就会输球头条创作挑战赛在很多人的记忆里,尤其是近些年才开始关注乒乓球的爱好者心中,都认为国乒非常强大,甚至不可战胜。尤其是前些年刘国梁提出养狼计划,很多人都觉得国乒已经强大到没有对手了,其CBA三消息北控欲签后卫老将,马布里提出要求,廖三宁独自特训大家好呀,我是北柠,各位小伙伴们要养成先赞后看的习惯哦!北控队这个休赛期基本没有什么本土球员的引进,他们下个赛季的目标依旧是冲击季后赛,说实话就目前北控队的实力看来,他们想要打进季2022年成都世乒赛团体赛运动员名单出炉成都世乒赛团体赛倒计时7天海报。国际乒联摄中新网成都9月23日电(记者贺劭清)23日,距离2022年第56届国际乒联世界乒乓球团体锦标赛(决赛)成都(简称成都世乒赛团体赛)开幕还有
ThinkPad衍生手机!联想全新系列ThinkPhone入网12月7日消息,摩托罗拉的一款型号为XT23091入网,支持68W快充。据数码博主WHYLAB透露,该机就是传闻中联想全新ThinkPhone系列,从名字就可以看出,该机是Thin现场直击快递物流业务量稳步上涨视频加载中国家邮政局监测数据显示,11月27日以来,全国快递日均业务量连续稳步上涨,特别是12月2日至4日,连续三天日均超3亿件,实现迅速反弹。当前,快递业仍处于旺季,在即将到来的每日好诗我突然明白,人出生时为什么哭,人离世时为什么笑每日好诗太阳在巡行太阳在巡行那条阴沟藏得很深几只塘虱在打洞太阳在巡行黄的,黑的,花的伞在流动有人在伞下说太阳的坏话有人在树下看石头读书太阳在巡行柏树对太阳敬礼笑看春夏和秋冬听说他也冬日里的童年记忆过年冬日生活打卡季冬日里的童年记忆十二月了,不知不觉间又一个年要过去了,不知是现在生活好了,还是自己长大了,或是从农村搬到城市里的缘故,对过年的概念已经很模糊了,也不像小时候那么盼着过天之箴言人之规行智慧使人幸福我人,你若接受我的话,把我的诫命存在心中,侧耳细听智慧,专心寻求睿智你若呼求明哲,扬声召寻睿智你若寻求她如寻求银子,搜索她如搜索宝藏,你必能领悟什么是敬畏上天,也能明白一个人好运来临之前,先要扛过这几件倒霉事人人都希望自己能够好运加身,受到幸运之神的青睐。其实,有一句话说得好命由天定,运在人为。我们虽然不能改变自己的出身,但是身上的运气,其实是靠自己去把控的。你越是懂得运作它,它就会源咦,这里有九款烤鱼口味配方大全,需要的可收藏烤鱼,是一种发源于重庆万州的特色美食,在流传过程中,融合腌烤炖三种烹饪工艺技术,充分借鉴传统川菜及川味火锅用料特点,是口味奇绝营养丰富的风味小吃。现今有各种烤鱼方式,包括米兰烤鱼石冬天,我家常备的维C小炸弹,孩子一口一个吃不停,特好吃今天很开心,因为大爆款,玲珑黄金圣女果,回归啦!这款黄金圣女果来自福建,酸甜味美,汁液丰富,而且全部是自然成熟,味道极为浓郁。它个头较小,比咱们常见的普通的圣女果要小一圈,所以,它今日大雪,多给家人吃这菜,简单炖一锅,解馋开胃,补充营养过冬头条创作挑战赛转眼之间,迎来冬天的第三个节气大雪节气,冬天是很多南方人最向往的季节,平常很少见到白雪皑皑,但是到了寒冬之后,就非常害怕寒冷,尤其是家里有孩子和老人,记得要多吃一些暖这个搭配太棒了,煮一煮,蒸一蒸,软软糯糯,营养又好吃前段时间做了一款紫米饼,很多朋友表示油酥面皮做起来太麻烦,而且又觉得热量比较高。虽然好吃,但是还是劝退了好多人。所以今天咱们来做个简单的,真的是一看就会,一做就成。同样的紫米馅,变美味猪头肉到了头号解忧馆一大早错过了顺丰快递的电话,猪头肉到达迟来了4个小时!本来是上午八点半送到家的,结果到12。30才收到。不过还好吧,好饭不怕晚。这猪头肉也太带劲了!即使是凉的,看起来依然