谈谈你对AQS的理解

AQS概述

AQS,全称为AbstractQueuedSynchronizer,是Java并发包(java.util.concurrent)中一个核心的框架,主要用于构建阻塞式锁和相关的同步器,也是构建锁或者其他同步组件的基础框架。AQS提供了一种基于FIFO(First-In-First-Out)的CLH(三个人名缩写)双向队列的机制,来实现各种同步器,如ReentrantLock、Semaphore、CountDownLatch等。

AQS与Synchronized的区别

|------------------|---------------------|
| synchronized | AQS |
| 关键字,c++ 语言实现 | java 语言实现 |
| 悲观锁,自动释放锁 | 悲观锁,手动开启和关闭 |
| 锁竞争激烈都是重量级锁,性能差 | 锁竞争激烈的情况下,提供了多种解决方案 |

AQS常见的实现类

  • ReentrantLock 阻塞式锁
  • Semaphore 信号量
  • CountDownLatch 倒计时锁

独占锁与共享锁

AQS 根据资源互斥级别提供了两种资源访问模式:独占锁 (exclusive)和共享锁 (shared)。独占锁一次只允许一个线程持有,如ReentrantLock。共享锁允许多个线程同时访问,如Semaphore和ReadWriteLock的读锁。同时其定义Condition结构提供了wait/signal等待唤醒机制。

原理概述

AQS维护了一个volatile int state变量和一个先进先出的CLH双向队列( 也叫等待队列,其中CLH为这个队列的三个发明者人名的缩写),队列中的节点Node持有线程引用,每个节点均可通过getState()、setState()和compareAndSetState()对state进行修改和访问。

state变量值用来表示锁的状态,0表示无锁,1表示有锁。

Node 节点包含线程的引用和节点的状态信息。

当线程获取锁时,即试图对state变量做修改,如修改成功则获取锁;如修改失败则包装为节点添加到双向队列中,等待持有锁的线程释放锁并唤醒双向队列中的节点。

工作机制

只有一个线程争抢 资源

当第一个线程0进入并通过CAS操作成功修改state值(即成功获取了锁或其他同步状态),此时该线程不会被封装成Node节点放到**CLH双向队列(等待队列)**中。

当第一个线程成功获取锁,此时来了2个线程,分别是线程1和线程2,它们想要获取锁,此时线程0还未释放锁,它们经过CAS操作后都获取锁失败,线程1和线程2就会被封装成Node节点并加入CLH双向队列(等待队列) 中进行排队,直到线程0释放锁后被唤醒,被唤醒的线程可以重新尝试获取锁。

如果多个线程共同去抢这个资源是如何保证原子性的呢?

当多个线程共同去修改state状态的时候,使用CAS自旋锁来保证原子性,确保只能有一个线程修改成功,修改失败的线程将会进入**CLH双向队列(等待队列)**中进行排队等待

AQS是公平锁吗,还是非公平锁?

  • 新的线程与队列中的线程共同来抢资源,是非公平锁
  • 新的线程到队列中等待,只让队列中的head线程获取锁,是公平锁

排队机制

**CLH双向队列(等待队列)**中Node节点的排队机制为:当队列为空时则使用尾插法向队列插入一个个使用线程封装好的Node节点,如果队列不为空,就向当前队列的尾部插入节点。总的来说还是使用尾插法插入Node节点

唤醒机制

AQS(AbstractQueuedSynchronizer)的唤醒机制中,唤醒的是**CLH双向队列(等待队列)**头节点的后继节点(即头节点的next节点),而不是头节点本身。 因为头节点通常是已经成功获取同步状态(如锁)的线程。这个线程正在执行它的临界区代码。

相关推荐
Piper蛋窝3 分钟前
Go 1.15 相比 Go 1.14 有哪些值得注意的改动?
后端
K8sCat10 分钟前
Golang与Kafka的五大核心设计模式
后端·kafka·go
不当菜虚困12 分钟前
JAVA设计模式——(四)门面模式
java·开发语言·设计模式
ruyingcai66666612 分钟前
用python进行OCR识别
开发语言·python·ocr
m0Java门徒20 分钟前
面向对象编程核心:封装、继承、多态与 static 关键字深度解析
java·运维·开发语言·intellij-idea·idea
小希爸爸20 分钟前
3、中医基础入门和养生
前端·javascript·后端
liuweidong080222 分钟前
【Pandas】pandas DataFrame radd
开发语言·python·pandas
摆烂工程师37 分钟前
ChatGPT免费用户可以使用Deep Research啦!并且o3、o4-mini的可使用次数翻倍!
前端·后端·程序员
_一条咸鱼_41 分钟前
揭秘 Android ListView:从源码深度剖析其使用原理
android·面试·android jetpack
_一条咸鱼_42 分钟前
深入剖析 Android NestedScrollView 使用原理
android·面试·android jetpack