美文网首页
AQS为什么要使用双向链表

AQS为什么要使用双向链表

作者: 刘大坝 | 来源:发表于2022-11-01 09:16 被阅读0次
高手:

首先,双向链表的特点是它有两个指针,一个指针指向前置节点,一个指针指向后继节点。

所以,双向链表可以支持 常量O(1) 时间复杂度的情况下找到前驱结点,基于这样的特点。

双向链表在插入和删除操作的时候,要比单向链表简单、高效。

因此,从双向链表的特性来看,我认为AQS使用双向链表有三个方面的考虑。

第一个方面

没有竞争到锁的线程加入到阻塞队列,并且阻塞等待的前提是,当前线程所在节点的前置节点是正常状态,

这样设计是为了避免链表中存在异常线程导致无法唤醒后续线程的问题。所以线程阻塞之前需要判断前置节点的状态,如果没有指针指向前置节点,就需要从head节点开始遍历,性能非常低。

判断前置节点状态.png
第二个方面

在Lock接口里面有一个,lockInterruptibly()方法,这个方法表示处于锁阻塞的线程允许被中断。

也就是说,没有竞争到锁的线程加入到同步队列等待以后,是允许外部线程通过interrupt()方法触发唤醒并中断的。

这个时候,被中断的线程的状态会修改成CANCELLED。

被标记为CANCELLED状态的线程,是不需要去竞争锁的,但是它仍然存在于双向链表里面。

意味着在后续的锁竞争中,需要把这个节点从链表里面移除,否则会导致锁阻塞的线程无法被正常唤醒。

在这种情况下,如果是单向链表,就需要从Head节点开始往下逐个遍历,找到并移除异常状态的节点。

同样效率也比较低,还会导致锁唤醒的操作和遍历操作之间的竞争。

Cancelled节点需要移除链表.png
第三个方面

为了避免线程阻塞和唤醒的开销,所以刚加入到链表的线程,首先会通过自旋的方式尝试去竞争锁。

但是实际上按照公平锁的设计,只有头节点的下一个节点才有必要去竞争锁,后续的节点竞争锁的意义不大。

否则,就会造成羊群效应,也就是大量的线程在阻塞之前尝试去竞争锁带来比较大的性能开销。

所以为了避免这个问题,加入到链表中的节点在尝试竞争锁之前,需要判断前置节点是不是头节点,如果不是头节点,就没必要再去触发锁竞争的动作。

所以这里会涉及到前置节点的查找,如果是单向链表,那么这个功能的实现会非常复杂。


竞争锁之前判断前置节点是否是head节点.png

原文链接:https://blog.csdn.net/q331464542/article/details/126123092

相关文章

  • Java面试——多线程与并发

    CAS的原理 AQS等待队列为什么设计成双向链表? juc包下知道哪些类? AQS,ReentrantLock,R...

  • AQS为什么要使用双向链表

    高手: 首先,双向链表的特点是它有两个指针,一个指针指向前置节点,一个指针指向后继节点。 所以,双向链表可以支持 ...

  • AQS双向链表

    双向链表的每个数据节点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方...

  • AQS原理剖析

    AQS结构剖析 双向链表 + waitStatus的int值 锁的结构: 实现Lock接口 组合AQS进行并发状态...

  • 慕课网高并发实战(七)- J.U.C之AQS

    7.1 AbstractQueuedSynchronizer -AQS 底层实现了双向链表,是队列的一种实现方式 ...

  • 2020-02-18 记录redis(3)

    存储-list ArrayList 使用数组方式 LinkList 使用双向链接方式 双向链表添加数据 双向链表删...

  • 五、双向链表

    双向链表 此前介绍的链表,也叫做单向链表使用双向链表可以提升链表的综合性能 修改之前的单链表的源码: 双向链表 –...

  • 数据结构课程 第四周 线性表--链式表循环链表

    循环链表更多的使用带尾指针的链表如果经常访问头尾指针,带尾指针的更方便 双向链表 双向链表的插入 双向链表的删除 ...

  • 33_双向循环链表的实现

    关键词:双向循环链表 0. 课程目标 使用Linux内核链表实现双向循环链表 template < typenam...

  • 五. java数据结构 - 双向链表

    1. 双向链表的操作分析和实现 使用带 head 头的双向链表实现 –水浒英雄排行榜 分析 双向链表的遍历,添加,...

网友评论

      本文标题:AQS为什么要使用双向链表

      本文链接:https://www.haomeiwen.com/subject/padrtdtx.html