详细理解AQS原理以及使用

什么是AQS

AbstractQueuedSynchronizer (抽象队列同步器,以下简称 AQS)出现在 JDK 1.5 中。AQS 是很多同步器的基础框架,比如ReentrantLockCountDownLatchSemaphore 等都是基于 AQS 实现的。除此之外,我们还可以基于 AQS,定制出我们所需要的同步器。
在这里插入图片描述

在AQS内部,维护了一个FIFO队列(内部类Node节点)和一个volatile的int类型的state变量。在state=1的时候表示当前对象锁已经被占有了,state变量的值修改的动作通过CAS来完成。
在这里插入图片描述

为什么需要AQS

先说说锁和协作类有共同点:让线程“协作”的功能

CountDownLatch是一个计数器,它允许一个或多个线程等待其他线程完成操作。它通常用来实现一个线程等待其他多个线程完成操作之后再继续执行的操作。

CyclicBarrier是一个同步屏障,它允许多个线程相互等待,直到到达某个公共屏障点,才能继续执行。它通常用来实现多个线程在同一个屏障处等待,然后再一起继续执行的操作。

Semaphore是一个计数信号量,它允许多个线程同时访问共享资源,并通过计数器来控制访问数量。它通常用来实现一个线程需要等待获取一个许可证才能访问共享资源,或者需要释放一个许可证才能完成操作的操作。

ReentraantLock是通过一个FIFO的等待队列来管理获取该锁所有线程的。在“公平锁”的机制下,线程依次排队获取锁;而“非公平锁”在锁是可获取状态时,不管自己是不是在队列的开头都会获取锁。

如果没有AQS

如果没有 AQS,那就需要每个线程协作工具类自己去实现至少以下内容

  • 状态的原子性管理
  • 线程的阻塞与解除阻塞
  • 队列的管理

如果没有 AQS,就需要 ReentrantLock 等类来自己实现相关的逻辑,但是让每个线程协作工具类自己去正确并且高效地实现这些内容,是相当有难度的。AQS 可以帮我们把 “脏活累活” 都搞定,所以对于 ReentrantLock 和 Semaphore 等类而言,它们只需要关注自己特有的业务逻辑即可。正所谓是“哪有什么岁月静好,不过是有人替你负重前行”

AQS的同步队列和条件队列原理

同步的队列的实现原理

  1. 当一个线程尝试获取锁并失败时,AQS会将该线程包装成一个节点(Node)并加入到队列的尾部。
  2. 这个节点会处于等待状态,直到锁被其他线程释放。
  3. 当锁被释放时,头节点(持有锁的线程)会通知其后继节点(如果存在的话),后继节点尝试获取锁。
  4. 这个过程会一直持续,直到有线程成功获取锁或者队列为空。

条件队列的实现原理

从上面的结构图可以看到ConditionObject是AQS的一个内部类主要用于实现条件变量。它允许一个或多个线程在特定条件成立之前等待,同时释放相关的锁。这在某种程度上类似于对象监视器模式中的wait()notify()方法,但提供了更灵活和更强大的控制。

  1. 当线程调用了Condition的await()方法后,它会释放当前持有的锁,并且该线程会被加入到条件队列中等待。
  2. 然后线程会处于等待状态,直到其他线程调用signal()signalAll()方法来通知条件可能已经满足。
  • 25
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值