AQS的细节--自用,非正常教程

AQS的概念

AQS叫抽象队列同步器,是一个框架,我们可以在JUC很多包看见AQS的具体实现,比如锁和读写锁,condition等,具有可扩展性,可以根据此自定义同步工具类,优点是系统开销低,实现锁比较灵活,可扩展性强,满足特殊需求。

AQS的核心思想

AQS核心思想是,如果被请求的共享资源空闲,那么就将当前请求资源的线程设置为有效的工作线程,将共享资源设置为锁定状态如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配
这个机制主要用的是CLH队列的变体实现的,将暂时获取不到锁的线程加入到队列中。AQS使用一个Volatile修饰的int类型的成员变量(State)来表示同步状态,通过内置的FIFO队列来完成资源获取的排队工作,通过CAS完成对State值的修改。

AQS的数据结构

维护一个volatile修饰的int变量state,表示同步状态;
有一个节点类,一个节点用来表示一个线程,节点里面有双向指针,也有一个volatile修饰的int表示线程状态(waitStatus);
还有一个同步队列,说是队列,实际上是一个双向链表,逻辑上是队列,只能有一个;
最后有一个条件队列,它是一个单向链表,可以有多个。
Node节点数据结构:
在这里插入图片描述
·····················································································································
在这里插入图片描述

AQS同步状态

AQS中维护了一个名为state的字段,意为同步状态,是由Volatile修饰的,用于展示当前临界资源的获锁情况。
对于我们自定义的同步工具,需要自定义获取同步状态和释放状态的方式,也就是自定义获取state的值,和改变state值的方法。

AQS对各种锁的实现

重入锁实现原理

例如ReentrantLock中,state = 0,表示还没有线程获取锁,state = 1,说明正在被使用,state > 1,表示被重入了,说明ReentrantLock自定义了state等于xxx的时候,各自代表了什么意思。

公平锁与非公平锁原理

记住一点,获取锁成功与否的标志是此线程是否成功用CAS改变了state,使其改成锁被获取的状态(比如重入锁中state=1为成功获取锁,那么如果有一个线程将state改成1,代表此线程成功获取锁),成功了就算获取锁。等到state变成0,这个时候谁会去获取锁便成了个问题,如果我们这样设计:获取锁之前先判断锁是否被获取,如果被获取,此线程将乖乖排到队尾,这样就能实现公平锁,因为避免了插队的发生嘛;如果这样设计:不作判断直接CAS尝试获取锁,竞争成功就插队,这样能实现非公平锁,因为节点无视排序直接僭越想抢锁,此为非公平嘛。

独占模式实现原理

独占和共享模式是通过修改State字段表示的同步状态来实现的(比如state只能等于0,1,那就肯定是独占锁;如果state最大等于n,那么最多允许n个线程共享数据)
独占模式顾名思义,只能一个线程使用锁,加锁过程是:如果加锁失败就进入队列,加入队列的时候,为了避免前面的线程是被中断的,或者是发生异常的,那如果不处理这种线程,那这辈子此节点也获取不了锁,于是它利用pre指针访问前驱节点判断前驱节点的状态,不对的就删除,直到到达一个正常节点的背后;锁释放后,为了找到正常节点,也会将后继异常节点清除直到找到合适的来唤醒
在这里插入图片描述

共享模式实现原理

顾名思义,锁是可共享的,于是如果一个节点获取了锁,那么它将唤醒后续其他想获取锁的,节点状态是共享的所有节点,直到碰到非共享状态节点,解锁也会唤醒后续线程。

在这里插入图片描述

其他应用场景

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值