电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

詳解Java回環屏障CyclicBarrier

瀏覽:5日期:2022-08-25 08:18:34

上一篇說的CountDownLatch是一個計數器,類似線程的join方法,但是有一個缺陷,就是當計數器的值到達0之后,再調用CountDownLatch的await和countDown方法就會立刻返回,就沒有作用了,那么反正是一個計數器,為什么不能重復使用呢?于是就出現了這篇說的CyclicBarrier,它的狀態可以被重用;

一.簡單例子

用法其實和CountDownLatch差不多,也就是一個計數器,當計數器的值變為0之后,就會把阻塞的線程喚醒:

package com.example.demo.study;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Study0216 { // 注意這里的構造器,第一個參數表示計數器初始值 // 第二個參數表示當計數器的值變為0的時候就觸發的任務 static CyclicBarrier cyclicBarrier = new CyclicBarrier(2, () -> { System.out.println('cyclicBarrier task '); }); public static void main(String[] args) { // 新建兩個線程的線程池 ExecutorService pool = Executors.newFixedThreadPool(2); // 線程1放入線程池中 pool.submit(() -> { try { System.out.println('Thread1----await-begin'); cyclicBarrier.await(); System.out.println('Thread1----await-end'); } catch (Exception e) { e.printStackTrace(); } }); // 線程2放到線程池中 pool.submit(() -> { try { System.out.println('Thread2----await-begin'); cyclicBarrier.await(); System.out.println('Thread2----await-end'); } catch (Exception e) { e.printStackTrace(); } }); // 關閉線程池,此時還在執行的任務會繼續執行 pool.shutdown(); }}

詳解Java回環屏障CyclicBarrier

 我們再看看CyclicBarrier的復用性,這里比如有一個任務,有三部分組成,分別是A,B,C,然后創建兩個線程去執行這個任務,必須要等到兩個線程都執行完成A部分,然后才能開始執行B,只有兩個線程都執行完成B部分,才能執行C:

package com.example.demo.study;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Study0216 { // 這里的構造器,只有一個參數,表示計數器初始值 static CyclicBarrier cyclicBarrier = new CyclicBarrier(2); public static void main(String[] args) { // 新建兩個線程的線程池 ExecutorService pool = Executors.newFixedThreadPool(2); // 線程1放入線程池中 pool.submit(() -> { try { System.out.println('Thread1----stepA-start'); cyclicBarrier.await();System.out.println('Thread1----stepB-start'); cyclicBarrier.await();System.out.println('Thread1----stepC-start'); } catch (Exception e) { e.printStackTrace(); } }); // 線程2放到線程池中 pool.submit(() -> { try { System.out.println('Thread2----stepA-start'); cyclicBarrier.await();System.out.println('Thread2----stepB-start'); cyclicBarrier.await();System.out.println('Thread2----stepC-start'); } catch (Exception e) { e.printStackTrace(); } }); // 關閉線程池,此時還在執行的任務會繼續執行 pool.shutdown(); }}

詳解Java回環屏障CyclicBarrier

二.基本原理

我們看看一些重要屬性:

public class CyclicBarrier { //這個內部類只有一個boolean值 private static class Generation { boolean broken = false; } //獨占鎖 private final ReentrantLock lock = new ReentrantLock(); //條件變量 private final Condition trip = lock.newCondition(); //保存線程的總數 private final int parties; //這是一個任務,通過構造器傳遞一個任務,當計數器變為0之后,就可以執行這個任務 private final Runnable barrierCommand; //這類內部之后一個boolean的值,表示屏障是否被打破 private Generation generation = new Generation(); //計數器 private int count;}

構造器:

//我們的構造器初始值設置的是partiespublic CyclicBarrier(int parties) { this(parties, null);}//注意,這里開始的時候是count等于parties//為什么要有兩個變量呢?我們每次調用await方法的時候count減一,當count的值變為0之后,怎么又還原成初始值呢?//直接就把parties的值賦值給count就行了呀,簡單吧!public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction;}

然后再看看await方法:

public int await() throws InterruptedException, BrokenBarrierException { try { //調用的是dowait方法 return dowait(false, 0L); } catch (TimeoutException toe) { throw new Error(toe); // cannot happen }}//假設count等于3,有三個線程都在調用這個方法,默認超時時間為0,那么首每次都只有一個線程可以獲取鎖,將count減一,不為0//就會到下面的for循環中扔到條件隊列中掛起;直到第三個線程調用這個dowait方法,count減一等于0,那么當前線程執行任務之后,//就會喚醒條件變量中阻塞的線程,并重置count為初始值3private int dowait(boolean timed, long nanos)throws InterruptedException, BrokenBarrierException, TimeoutException { //獲取鎖 final ReentrantLock lock = this.lock; lock.lock(); try { //g中只有一個boolean值 final Generation g = generation; //如果g中的值為true的時候,拋錯 if (g.broken) throw new BrokenBarrierException(); //如果當前線程中斷,就拋錯 if (Thread.interrupted()) { breakBarrier(); throw new InterruptedException(); } //count減一,再賦值給index int index = --count; //如果index等于0的時候,說明所有的線程已經到屏障點了,就可以 if (index == 0) { // tripped boolean ranAction = false; try { //執行當前線程的任務 final Runnable command = barrierCommand; if (command != null) command.run(); ranAction = true; //喚醒其他因為調用了await方法阻塞的線程 nextGeneration(); return 0; } finally { if (!ranAction) breakBarrier(); } } //能到這里來,說明是count不等于0,也就是還有的線程沒有到屏障點 for (;;) { try { //wait方法有兩種情況,一種是設置超時時間,一種是不設置超時時間 //這里就是對超時時間進行的一個判斷,如果設置的超時時間為0,則會在條件隊列中無限的等待下去,直到被喚醒 //設置了超時時間,那就等待該時間 if (!timed) trip.await(); else if (nanos > 0L) nanos = trip.awaitNanos(nanos); } catch (InterruptedException ie) { if (g == generation && ! g.broken) { breakBarrier(); throw ie; } else { Thread.currentThread().interrupt(); } } if (g.broken) throw new BrokenBarrierException(); if (g != generation) return index; if (timed && nanos <= 0L) { breakBarrier(); throw new TimeoutException(); } } } finally { //釋放鎖 lock.unlock(); }}//喚醒其他因為調用了await方法阻塞的線程private void nextGeneration() { //喚醒條件變量中所有線程 trip.signalAll(); //重置count的值 count = parties; generation = new Generation();}private void breakBarrier() { generation.broken = true; //重置count為初始值parties count = parties; //喚醒條件隊列中的所有線程 trip.signalAll();}

以上就是詳解Java回環屏障CyclicBarrier的詳細內容,更多關于Java CyclicBarrier的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
主站蜘蛛池模板: 网站优化公司_SEO优化_北京关键词百度快速排名-智恒博网络 | 电加热导热油炉-空气加热器-导热油加热器-翅片电加热管-科安达机械 | Eiafans.com_环评爱好者 环评网|环评论坛|环评报告公示网|竣工环保验收公示网|环保验收报告公示网|环保自主验收公示|环评公示网|环保公示网|注册环评工程师|环境影响评价|环评师|规划环评|环评报告|环评考试网|环评论坛 - Powered by Discuz! | 电力测功机,电涡流测功机,磁粉制动器,南通远辰曳引机测试台 | 不锈钢酒柜|恒温酒柜|酒柜定制|酒窖定制-上海啸瑞实业有限公司 | 安全,主动,被动,柔性,山体滑坡,sns,钢丝绳,边坡,防护网,护栏网,围栏,栏杆,栅栏,厂家 - 护栏网防护网生产厂家 | 小型高低温循环试验箱-可程式高低温湿热交变试验箱-东莞市拓德环境测试设备有限公司 | 全自动真空上料机_粉末真空上料机_气动真空上料机-南京奥威环保科技设备有限公司 | COD分析仪|氨氮分析仪|总磷分析仪|总氮分析仪-圣湖Greatlake | 汕头市盛大文化传播有限公司,www.11400.cc | 折弯机-刨槽机-数控折弯机-数控刨槽机-数控折弯机厂家-深圳豐科机械有限公司 | 广东燎了网络科技有限公司官网-网站建设-珠海网络推广-高端营销型外贸网站建设-珠海专业h5建站公司「了了网」 | 远程会诊系统-手术示教系统【林之硕】医院远程医疗平台 | 机器视觉检测系统-视觉检测系统-机器视觉系统-ccd检测系统-视觉控制器-视控一体机 -海克易邦 | 口臭的治疗方法,口臭怎么办,怎么除口臭,口臭的原因-口臭治疗网 | 食品无尘净化车间,食品罐装净化车间,净化车间配套风淋室-青岛旭恒洁净技术有限公司 | 运动木地板_体育木地板_篮球馆木地板_舞台木地板-实木运动地板厂家 | pbt头梳丝_牙刷丝_尼龙毛刷丝_PP塑料纤维合成毛丝定制厂_广州明旺 | 蜘蛛车-登高车-高空作业平台-高空作业车-曲臂剪叉式升降机租赁-重庆海克斯公司 | 红酒招商加盟-葡萄酒加盟-进口红酒代理-青岛枞木酒业有限公司 | 吹田功率计-长创耐压测试仪-深圳市新朗普电子科技有限公司 | 丙烷/液氧/液氮气化器,丙烷/液氧/液氮汽化器-无锡舍勒能源科技有限公司 | 滚珠丝杆升降机_螺旋升降机_丝杠升降机-德迈传动 | ◆大型吹塑加工|吹塑加工|吹塑代加工|吹塑加工厂|吹塑设备|滚塑加工|滚塑代加工-莱力奇塑业有限公司 | 3d可视化建模_三维展示_产品3d互动数字营销_三维动画制作_3D虚拟商城 【商迪3D】三维展示服务商 广东健伦体育发展有限公司-体育工程配套及销售运动器材的体育用品服务商 | 雨燕360体育免费直播_雨燕360免费NBA直播_NBA篮球高清直播无插件-雨燕360体育直播 | 超声波气象站_防爆气象站_空气质量监测站_负氧离子检测仪-风途物联网 | 定时排水阀/排气阀-仪表三通旋塞阀-直角式脉冲电磁阀-永嘉良科阀门有限公司 | 高铝矾土熟料_细粉_骨料_消失模_铸造用铝矾土_铝酸钙粉—嵩峰厂家 | 自动气象站_农业气象站_超声波气象站_防爆气象站-山东万象环境科技有限公司 | 苏州工作服定做-工作服定制-工作服厂家网站-尺品服饰科技(苏州)有限公司 | 上海公司注册-代理记账-招投标审计-上海昆仑扇财税咨询有限公司 上海冠顶工业设备有限公司-隧道炉,烘箱,UV固化机,涂装设备,高温炉,工业机器人生产厂家 | 大功率金属激光焊接机价格_不锈钢汽车配件|光纤自动激光焊接机设备-东莞市正信激光科技有限公司 定制奶茶纸杯_定制豆浆杯_广东纸杯厂_[绿保佳]一家专业生产纸杯碗的厂家 | 国际线缆连接网 - 连接器_线缆线束加工行业门户网站 | 润滑脂-高温润滑脂-轴承润滑脂-食品级润滑油-索科润滑油脂厂家 | 隐形纱窗|防护纱窗|金刚网防盗纱窗|韦柏纱窗|上海青木装潢制品有限公司|纱窗国标起草单位 | 丝杆升降机-不锈钢丝杆升降机-非标定制丝杆升降机厂家-山东鑫光减速机有限公司 | 熔体泵_熔体出料泵_高温熔体泵-郑州海科熔体泵有限公司 | 全自动面膜机_面膜折叠机价格_面膜灌装机定制_高速折棉机厂家-深圳市益豪科技有限公司 | 活性炭-果壳木质煤质柱状粉状蜂窝活性炭厂家价格多少钱 | 实木家具_实木家具定制_全屋定制_美式家具_圣蒂斯堡官网 |