Java多线程——AQS框架源码阅读

AQS,全称AbstractQueuedSynchronizer,是Concurrent包锁的核心,没有AQS就没有Java的Concurrent包。它到底是个什么,我们来看看源码的第一段注解是怎么说明

 

 


看完第一段,总结下

 

  • AQS是一个同步的基础框架,基于一个先进先出的队列。
  • 锁机制基于一个状态值,它是原子值。
  • AQS的子类负责定义与操作这个状态值,但必须通过AQS提供的原子操作
  • AQS剩余的方法就是围绕队列,与线程阻塞唤醒等功能

基于以上概念,我们看看源码到底是这么实现这些功能的

AQS的成员变量

state

private volatile int state;
该变量标记为volatile,说明该变量是对所有线程可见的。作用在于每个线程改变该值,都会马上让其他线程可见,在CAS(可见锁概念与锁优化)的时候是必不可少的。在AQS类中,不会直接操作这个值,而是交由它的子类去操作和定义他的作用。

Node、head、tail

AQS中有一个静态内部类Node,其实现是一个双向链表。headtail则是这个链表的头尾指针。作用是存储获取锁失败的阻塞线程。同样的,这个链表是会被多个线程操作的,所以它里面的变量多是被标记为volatile,并且操作也要通过CAS等原子方法去执行。
Node还有一个模式的属性:独占模式共享模式。独占模式下,锁是线程独占的,而共享模式下,锁是可以被多个线程占用的。

 

VarHandler

对于大多数需要操作的原子属性,都对应会有一个大写的值,它的类是VarHandler。例如state、head、tail都有对应的VarHandler,STATE、HEAD、TAIL。VarHandler是1.9的新特性,提供了类似于原子操作以及Unsafe操作的功能,里面的原子操作大多是native方法,比较难查看源码。

 

ConditionObject

条件队列,是AQS中一个非常关键内部类。这个名字起非常奇异,让人搞不懂,看它类注释也看不懂说了什么。看看AQS头部注解


这个类是为了让子类支持独占模式的。深入看其中的源码实现,其实就是Node在功能性上的封装,最终让子类实现让当前线程怎么独占一个Object锁。await()、dosign()等方法就是让线程阻塞、加入队列、唤醒线程等。AQS框架下基本各种独占的加锁,解锁等操作到最后都是基于这个类实现的。该类是提供给子类去使用的,具体实现等下次说ReentranLock再深入了解。有人可能觉得为什么实现这个内部类,又不用,而是给子类去用,那为什么不放到子类去呢?其实答案,很简单,抽象加模板模式


p.s. 只有独占锁才能配合该类使用。

 

AQS的成员函数

AQS的公用的方法,主要是加锁与解锁方法。以下方法只提供了模板,部分实现还是在子类当中,直接调用会抛出异常。

acquire()

尝试获取锁,失败则进入队列。


先执行tryAcquire()(子类实现),成功则直接返回,如果是获取锁失败,则执行addWaiter(),通过CAS在双向链表的尾部添加一个新独占节点。


然后把节点丢到acquireQueued()中执行。该方法其实就是自旋尝试获取锁或阻塞线程(子类实现决定)。一开始,获取新节点的前驱节点,如果这个节点是head,则证明只有两个节点,此时再次执行tryAcquire()尝试获取锁,若获取成功,则不需要中断,成功结束。


如果还是获取失败,则执行shouldParkAfterFailedAcquire(),根据前驱节点状态(子类设值)判断是否继续自旋(当waitStatus为初始值,重复上一步,直到前面的节点一直在减少到前驱节点为head)或者阻塞线程(当waitStatus标记为SIGNAL)


最后如果acquireQueued()返回需要阻塞,则执行selfInterrupt()设置线程为中断


可以看回acquire()函数的写法,十分的艺术。利用条件判断的短路规则,实现在if()条件内嵌套判断执行语音。一般人(笔者本人)如果要实现这个功能,会这么写

 

所以下次遇到类似嵌套if条件判断的语句,可以学习下acquire()的这种短路写法。赞?

acquireInterruptibly()

检查线程是否被中断并尝试获取锁,失败则进入队列。线程中断会退出队列。
流程基本和acquire()相同。不同点就是,acquireInterruptibly()在自旋获取过程中如果线程是中断的,那么就会抛出异常退出流程,并且放弃锁。


doAcquireInterruptibly()方法与acquireQueued()方法非常相似,不同就是前者在中断状态下,不会再继续获取锁。注意最后有cancelAcquire()方法的执行。

 

tryAcquireNanos()

尝试获取锁,失败则进入队列。当超过指定时间或线程中断会退出队列。
acquireInterruptibly()基础上,增加多一个时间判断,超过指定时间,则退出,放弃获取锁。

 

release()

释放当前锁,并唤醒下一个Node。
尝试释放锁


若释放成功,且waitStatus不为0(证明是SIGNAL的),就会执行unparkSuccessor(),先取消SIGNAL标志,然后找到最近一个需要SIGNAL的节点,并且唤醒它。

 

**shared()

以上方法皆为独占模式,对应都有共享模式的方法。最大的不同其实就是Node的waitStatus值为PROPAGATE。具体流程与独占大体相同,细节留到ReentrantReadWriteLock再细了解。

总结

回顾下要点

  1. AQS是一个同步的基础框架,是ReentranLock、ReentranReadWriteLock的父类
  2. AQS原理是维护一个state原子值,通过一个双向链表的队列实现同步。
  3. 对于state、与队列的操作都是原子操作,通过VarHandle实现
  4. 主要对外方法是加锁与解锁,区别是否中断、超时、共享或独占模式

以上即使AQS的大致内容,可能有些部分难以理解,其实很正常,因为AQS提供的是流程模板与工具,没有实质落地的场景,是比较难理解的。等后面介绍ReentranLockReentrantReadWriteLock的时候,就可以更好更全面的了解整体AQS框架了。

以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化中的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值