java并发编程 10:AQS

什么是AQS

juc包的结构如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZlrXs1em-1689247459660)(./imgs/10-1.png)]

AQS就是AbstractQueuedSynchronizer,是个抽象类,实现了自己的一些方法。它是阻塞式锁和相关的同步器工具的框架。很多并发类都是基于它实现的,如:ReentrantLock、CountDownLatch、Semaphore、ReadWriteLock,CyclicBarrier。

AQS的设计是基于模板方法模式的,也就是说,使用者需要继承同步器并重写指定的方法,随后将同步器组合在自定义同步组件的实现中,并调用同步器提供的模板方法,而这些模板方法将会调用使用者重写的方法,这样就大大降低了实现一个可靠自定义同步组件的门槛。

子类主要实现以下抽象方法:

  • tryAcquire:独占方式获取锁
  • tryRelease:独占方式释放锁
  • tryAcquireShared:共享方式获取锁
  • tryReleaseShared:共享方式释放锁
  • isHeldExclusively:该线程是否正在独占资源

原理

  1. 状态管理

AQS内部通过一个整型变量来表示同步状态,用于标识资源是否被占用或者线程是否可以获取资源。通常情况下,状态为0表示资源未被占用,大于0表示资源已被占用,小于0表示资源已被占用且有等待线程。

  1. 队列管理

AQS使用一个FIFO队列来管理等待获取资源的线程。AQS提供了一些方法(如enq、addWaiter和unparkSuccessor)来操作队列。

当前线程获取同步状态失败时,同步器会将当前线程以及等待状态等信息构造成为一个节点(Node)并将其加入同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点中的线程唤醒,使其再次尝试获取同步状态。节点(Node)用来保存获取同步状态失败的线程引用、等待状态以及前驱和后继节点。同步队列的基本结构如图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zVSC1c62-1689247459661)(./imgs/10-2.png)]

  1. acquire方法

acquire方法是AQS的核心方法之一,用于实现线程对资源的获取。当线程调用acquire方法时,AQS首先会通过尝试CAS(Compare and Set)操作来竞争资源。如果成功获取资源,则线程可以继续执行;否则,线程将被加入到等待队列中,进入阻塞状态,直到资源被释放。

  1. release方法

    release方法是AQS的另一个核心方法,用于实现线程对资源的释放。当线程调用release方法时,AQS会先将同步状态更新为0,然后尝试唤醒等待队列中的其他线程,使它们有机会重新竞争资源。

  2. 共享模式和独占模式

    AQS支持两种同步模式:独占模式和共享模式。独占模式表示同一时间只能有一个线程持有资源,而共享模式则允许多个线程同时持有资源。AQS提供了对应的acquire和release方法来支持这两种模式,并且可以在不同的同步器中灵活地选择使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ethan-running

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值