aqs java 非公平锁_透过ReentrantLock窥探AQS

背景

JDK1.5引入的并发包提供了一系列支持中等并发的类,这些组件是一系列的同步器,几乎任一同步器都可以实现其他形式的同步器,例如,可以用可重入锁实现信号量或者用信号量实现可重入锁。但是,这样做带来的复杂性,开销,不灵活使其至多只能是个二流工程,且缺乏吸引力。如果任何这样的构造方式不能在本质上比其他形式更简洁,那么开发者就不应该随意地选择其中的某个来构建另一个同步器,所以JSR166建立了一个小框架-AQS(由Doug Lea设计),对这些同步器做了统一的抽象,为构造同步器提供了通用的机制,之后并发包中大部分同步器都基于AQS来实现。

注:本文通过ReentrantLock来窥探AQS的结构以及运行原理,因为AQS是并发包实现大部分同步器的框架,所以本文只对ReentrantLock相关方法做了解释说明,其他的方法在后面的文章中会继续做深入的解释

AQS设计

301aacd97505121ebe44ec01a9c6fce3.png

这是ReentrantLock中的内部类Sync的类图,图中可以看出Sync抽象类实现了AbstractQueuedSynchronizer。

ReentrantLock实现

ReentrantLock提供了非公平锁以及公平锁的能力,实现Lock接口,通过把功能实现委托给Sync同步器来实现。下面以非公平锁为例子,开始图解ReentrantLock类在调用lock方法时候的过程:

首先看下AQS的数据结构以及Node节点的结构

64b11d33c5a852c659a0d3121aadd1d5.png

AQS的数据结构中state是最核心的变量,用来判断当前同步器是否有被线程占用,以及被同一个线程重入了多少次(重入锁实现的关键);

exclusiveOwerThread表示当前是哪个线程占用着同步器;

head是一个指向空的头结点的引用地址;

tail是一个指向等待同步器的最后一个节点的引用地址;

a857b45fb28ae2a8aa06322c062fa4e1.png

Node节点中最核心的是waitStatus,此处waitStatus的取值分别可以为:

1表示等待的线程已经取消或者中断;

-1表示后一个节点需要唤醒,当前节点如果释放锁,则需要唤醒后继节点;

-2表示当前的节点是一个条件等待,即需要等待其他的条件满足才能够被加入到同步队列,等待被唤醒

-3表示下一个acquireShared应无条件传播(在读写锁中会遇到,后面会专门写文章分析读写锁)

0表示初始状态

看完AQS的数据结构之后,我们再图解ReentrantLock非公平锁的lock方法,看下代码

<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值