资讯专栏INFORMATION COLUMN

AbstractQueuedSynchronizer(AQS)

Coding01 / 1983人阅读

摘要:线程将再次尝试获取锁定以确保它在实际停放之前无法获取。如果没有头,则表示队列中没有线程,因此没有人发出信号。如果后继节点未处于取消状态,则取消后继节点的线程,以便它可以重试获取。

摘要排队同步器类
它提供了一个框架,用于实现阻塞锁和相关的同步器,如信号量, CountDownLatch等。获取的基本算法是try acquire,如果成功则返回其他排队线程(如果它尚未排队)并阻止当前线程。同样,发布的基本算法是try release,如果成功,则取消阻塞队列中的第一个线程,否则只返回。线程将在先进先出(FIFO)等待队列中等待。抽象方法 tryAcquire()和tryRelease()将根据需要由子类实现。

以独家模式获取
以独占模式获取的通用算法
AbstractQueuedSynchronizer(AQS)

在上面的图中"shouldParkAfterFailedAcquire?" 验证前任的等待状态是否为SIGNAL。如果是,它确定前任线程将在其释放时SIGNAL,因此它将立即阻止,否则它可能会重试获取锁,以防它是队列中的第一个节点。
AbstractQueuedSynchronizer(AQS)

队列
如果线程无法获取锁,它将被放入队列中。如果队列尚不存在,它将使用虚拟标头初始化它,然后将其自身链接到它。头部的“下一个”和节点的“上一个”将被链接。新节点也成了尾巴。标题节点的等待状态将设置为SIGNAL,以便当所有者线程释放锁时,它可以通知头节点的后继者获取锁。线程将再次尝试获取锁定以确保它在实际停放之前无法获取。

AbstractQueuedSynchronizer(AQS)

因此,只要其前任节点的等待状态被设置为SIGNAL,就可以安全地停放未能获得锁的线程,因此一旦前一个被释放,它就可以重试获取锁。
如果前一个被取消,它将跳过所有被取消的前任,以重置其等待线程的next和prev指针。

AbstractQueuedSynchronizer(AQS)
发布
AbstractQueuedSynchronizer(AQS)

子类将根据他们的要求实现“try Release”。一旦发布,标头节点的后继节点需要发信号,以便它可以重新尝试获取。如果没有头,则表示队列中没有线程,因此没有人发出信号。如果磁头存在,则确保等待状态不为零。如果它为零,则意味着不需要发信号通知后继节点。

Unpark后继节点的线程
线程到unpark是在后继节点,通常只是下一个节点。
情况1:如果头部的等待状态<0,则清除等待状态。如果后继节点(P1)未处于取消状态,则取消后继节点的线程,以便它可以重试获取。
AbstractQueuedSynchronizer(AQS)

情况2:如果后继节点取消或为null,则从尾部向后遍历以查找实际未取消的后继节点。
AbstractQueuedSynchronizer(AQS)

一旦取消停放线程,其节点就成了新头。老头将脱钩。如果未能获得,将重新停放。头节点的等待状态设置为0将重置为SIGNAL。

发布共享
这与独家发布类似。它还确保释放传播。

以共享模式获取
这类似于独家收购。它还将释放传播到队列中等待获取共享锁的其他等待线程。一旦锁定被释放,它就会取消其后继节点的停放,后者又将释放传播到下一个节点。

取消
在尝试获取时可能存在运行时异常,在这种情况下将取消上下文中的节点。如果节点被取消,我们必须确保其后继节点正确链接到有效的前任节点,因此可能必须调整链接。如果其前任节点已经处于取消状态,则将跳过这些节点以到达具有等待状态<= 0的适当的前任节点。
如果要取消的节点本身是尾节点,则将简单地将其移除。它的前身节点将成为新的尾巴。新尾部的“下一个”链接将指向null。
如果等待状态<0,则表示后继者需要信号,尝试设置前任的下一个链接,以便获得一个。如果前任是头节点本身,则它将唤醒其后继节点。

情况1:要取消的节点是尾节点
AbstractQueuedSynchronizer(AQS)

情况2:取消节点的前任是head,现在将发信号通知被取消节点的下一个节点被唤醒。
原文地址:https://www.javarticles.com/2...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77905.html

相关文章

  • AbstractQueuedSynchronizerAQS

    摘要:线程将再次尝试获取锁定以确保它在实际停放之前无法获取。如果没有头,则表示队列中没有线程,因此没有人发出信号。如果后继节点未处于取消状态,则取消后继节点的线程,以便它可以重试获取。 摘要排队同步器类它提供了一个框架,用于实现阻塞锁和相关的同步器,如信号量, CountDownLatch等。获取的基本算法是try acquire,如果成功则返回其他排队线程(如果它尚未排队)并阻止当前线...

    Keagan 评论0 收藏0
  • 读源码笔记 Java AbstractQueuedSynchronizer

    摘要:总结总的来说,操作顺序是进入队列唤醒,成功获得锁将状态变为并将其从转到使再次获得锁执行余下代码。当然这是理由状态下,为了讨论及的原理,实际的操作时序也有可能变化。 AQS Condition 最近面试被问到java concurrent包下有哪些熟悉的,用过的工具。因此来回顾一下,这些工具的底层实现,AbstractQueuedSynchronizer。在网上看到了其他人的一些技术博客...

    selfimpr 评论0 收藏0
  • 读源码笔记 Java AbstractQueuedSynchronizer

    摘要:总结总的来说,操作顺序是进入队列唤醒,成功获得锁将状态变为并将其从转到使再次获得锁执行余下代码。当然这是理由状态下,为了讨论及的原理,实际的操作时序也有可能变化。 AQS Condition 最近面试被问到java concurrent包下有哪些熟悉的,用过的工具。因此来回顾一下,这些工具的底层实现,AbstractQueuedSynchronizer。在网上看到了其他人的一些技术博客...

    YuboonaZhang 评论0 收藏0
  • 【JDK源码】同步系列AQS初识

    摘要:文章目录简介核心源码主要内部类主要属性子类需要实现的主要方法基于自己动手写一个锁总结简介的全称是,它的定位是为中几乎所有的锁和同步器提供一个基础框架。 文章目录 ...

    pkhope 评论0 收藏0
  • AbstractQueuedSynchronizer超详细原理解析

    摘要:如果此时,锁被释放,需要通知等待线程再次尝试获取锁,公平锁会让最先进入队列的线程获得锁。等待队列节点的操作由于进入阻塞状态的操作会降低执行效率,所以,会尽力避免试图获取独占性变量的线程进入阻塞状态。  今天我们来研究学习一下AbstractQueuedSynchronizer类的相关原理,java.util.concurrent包中很多类都依赖于这个类所提供队列式同步器,比如说常用的R...

    yck 评论0 收藏0

发表评论

0条评论

Coding01

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<