相濡以沫共进退 -- CyclicBarrier

一:风骚概述

LOL进入游戏等待,很多召唤师都喜欢说你家用的小霸王吧?等待最慢一个召唤师加载100%后再开始展开召唤师峡谷的剧情,保证游戏公平。其实对于倒数计数器CountDownLatch与栅栏CyclicBarrier的区别个人认为仁者见仁智者见智,场景有重叠与特例,只要掌握其核心实现原理与功能,才能选择最佳的实现方式

二:重要属性

在这里插入图片描述

  • lock:独占锁保障线程安全
  • trip:condition实例睡眠线程等待
  • parties:栅栏阻碍线程数量
  • barrierCommand:开启栅栏后执行的线程
  • generation:描述栅栏是否被破坏
三:栅栏厚度

CyclicBarrier作用就是等待N数量线程后唤醒所有等待线程开始执行,那么这个N的数量级相关设定就显得尤为重要

3.1 初始化赋值

在这里插入图片描述
实例化CyclicBarrier对象时会传参parties指定栅栏的厚度,第二个参数是后续会讲到的当栅栏开启后会执行的线程。构造函数还有一个仅仅传入参数parties数量的重载,该构造函数调用上图所示构造,参数barrierAction默认为null

3.2 更新赋值

栅栏CyclicBarrier与倒数计数器CountDownLatch有一个重要的区别就是栅栏可以重复使用,其实现就是原理就是重置栅栏厚度。通过前面的构造函数还可以得到一个信息就是栅栏的厚度会赋值给count,该属性才是记录当前运行时栅栏厚度,而栅栏初始赋值参数使用parties保存
在这里插入图片描述
通过reset()就会重置栅栏厚度,但是这时候中间过程会唤醒所有栅栏等待线程,且栅栏状态为破损,有可能会抛出BrokenBarrierException异常,需要做必要的异常处理

四:核心方法

CyclicBarrier栅栏的核心方法就是await(),这个方法中包含栅栏状态检测、栅栏厚度检测、线程睡眠等待、等待线程唤醒、栅栏重置等操作

4.1 栅栏状态检测

在这里插入图片描述
静态内部类Generation维护布尔值broken标记栅栏是否被破坏,当发生InterruptedException异常或是重置栅栏的时候都会将该状态设置为true,这时候若还有线程调用await()则会抛出BrokenBarrierException异常

4.2 栅栏厚度检测

在这里插入图片描述
在这个dowait()片段中可以看到栅栏厚度判断是通过count属性,并且当栅栏厚度为0的时候就会开始执行barrierCommand线程,也就是前面讲到实例化入参的barrierAction线程参数

4.3 线程等待与唤醒

在这里插入图片描述
死循环让线程睡眠,通过condition实例trip实现。注意await()方法具备重载,也就是可以指定在栅栏面前等待的时间。注意一点就是当线程等待时间超过设定值的时候会抛出TimeoutException异常,注意异常处理
在这里插入图片描述
栅栏厚度判断为0的时候会调用方法nextGeneration(),方法中唤醒所有condition睡眠线程,同时恢复栅栏状态和厚度

4.4 栅栏受损

在这里插入图片描述
栅栏受损即抛出标记检测异常InterruptedException等的时候会调用方法brekBarrier(),该方法同样会唤醒所有condition睡眠线程,但是注意这里会将栅栏状态设置为破损。所以其它线程执行注意处理BrokenBarrierException异常

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值