虽然前面也看过AQS的文章,并且转载过一篇大佬的分析,但是我觉得他们对于AQS和ReentrantLock部分的源码的分析并不详细,自己理解期来还是有问题,于是自己准备花时间重新梳理下,好了,进入正题。

第一个线程过来加锁



我们看的是非公平锁的,这里进入nonfair实现:



代码如下:



由于这是第一个线程过来获取锁,所以这里通过cas方式加锁成功,即通过compareAndSetState方法,成功的将state共享变量的值设置为1,并将the owner thread设置为当前线程。这里假设大家已经看过前面连篇关于cas的文章了AQS简单理解入门彻底掌握 AQS

这里线程1已经加锁成功了,我们假设它暂时是不会释放锁的,因为主要是看aqs内部的队列。

第二个线程尝试过来加锁

和第一个线程一样,仍然走进lock方法的非公平实现:



但是此时由于线程1已经加锁成功,所以cas是失败的,进入到else块的acqure方法里



这里可以看到,进入acquire方法里,是先调用tryAcquire方法,尝试下,看看能不能加上锁,万一线程1释放了锁呐,这样就不用入队列,我们直接进入到非公平锁的nonfairTryAcquire方法:



由于我们假设线程1需要占用很久,所以这时tryAcquire()获取锁是失败的,返回为false:



这里我们先进去这个addWaiter方法:

在分析这个方法之前,需要先补充下双向链表的知识,要不这里会迷,我们先看官方源码中的注释:



由于线程1成功获取锁,并没有被阻塞放入CLH队列,且这里由于clh队列是懒加载的,并没有初始化,这时,head和tail指针指向的头尾node节点均为null:

进入addWaiter:



进入enq方法,参数为node = new Node(Thread.currentThread(), null);



这里来张图展示下clh队列的变化:



方法enq执行完出来后,addWaiter方法也执行结束,并返回创建的node:



此时回到调用addWaiter方法处,进入acquireQueued方法:



但是排在队列第二位的线程,如果尝试几次不成功后,也会像后面的线程一样,最后走进shouldParkAfterFailedAcquire()方法:

这里暂时不分析了,通过上面的分析,已经达到本文的目的,理解clh队列的创建和变化过程。

从ReentrantLock实现非公平锁的源码理解AQS中的CLH队列的更多相关文章

  1. ReentrantLock获取到非公平锁的源码

    /** * Performs lock. Try immediate barge, backing up to normal * acquire on failure. */ final void l ...

  2. 基于ReentrantLock的非公平锁理解AQS

    AQS AQS概述 ​ AbstractQueuedSynchronizer抽象队列同步器简称AQS,它是实现同步器的基础组件,juc下面Lock的实现以及一些并发工具类就是通过AQS来实现的,这里我 ...

  3. ReentrantLock之非公平锁源码分析

    本文分析的ReentrantLock所对应的Java版本为JDK8. 在阅读本文前,读者应该知道什么是CAS.自旋. 由于ReentrantLock的公平锁和非公平锁中有许多共同代码,本文只会对这两种 ...

  4. 源码解析C#中PriorityQueue(优先级队列)的实现

    前言 前段时间看到有大佬对.net 6.0新出的PriorityQueue(优先级队列)数据结构做了解析,但是没有源码分析,所以本着探究源码的心态,看了看并分享出来.它不像普通队列先进先出(FIFO) ...

  5. ReentrantLock源码探究1:非公平锁的获取和释放

    1.AQS简单介绍 ​ Sync是ReentrantLock的一个内部类,它继承了AbstractQueuedSynchronizer,即AQS,在CountDownLatch.FutureTask. ...

  6. 深入了解ReentrantLock中的公平锁和非公平锁的加锁机制

    ReentrantLock和synchronized一样都是实现线程同步,但是像比synchronized它更加灵活.强大.增加了轮询.超时.中断等高级功能,可以更加精细化的控制线程同步,它是基于AQ ...

  7. ReentrantLock 非公平锁不公平在哪

    重入锁关键地带: 1:使用unsafe的cas方式对AQS中的state成员变量进行“原子加一”操作. 2:如果当前线程多次lock,相当于对state在原有值基础上继续加一操作:释放锁的条件为“原子 ...

  8. lesson3.1:java公平锁和非公平锁及读写锁

    关于这四种锁的各自情况,网上有很多文章做了介绍,本不想单独开章节介绍,本章只介绍这四种锁的一些源码特点及注意事项. demo 源码:https://github.com/mantuliu/javaAd ...

  9. Java并发指南8:AQS中的公平锁与非公平锁,Condtion

    一行一行源码分析清楚 AbstractQueuedSynchronizer (二) 转自https://www.javadoop.com/post/AbstractQueuedSynchronizer ...

随机推荐

  1. Java 初中级程序员如何快速成长???

    Java 技术学习路线 Java 语言是一门非常流行和重要的语言,目前仍是需求量很大的语言,应用范围很广的语言,在企业级开发.移动开发.大数据云计算.人工智能等领域都有大量的应用. 怎么样学习好 Ja ...

  2. git 合并多次commit

    如果当前分支提交了多次commit,无法merge到master上,就需要合并多出的几次commit 第一步 查看log: git log 第二步 git rebase -i HEAD~2 对最近的两 ...

  3. Hbase之过滤器的使用

    一.过滤器概念 基础API中的查询操作在面对大量数据的时候是非常物无力的,这里Hbase提供了高级的查询方法:Filter(过滤器).过滤器可以根据簇.列.版本等更多的条件来对数据进行过滤,基于Hba ...

  4. SQL中的主键,候选键,外键,主码,外码

    1.码=超键:能够唯一标识一条记录的属性或属性集. 标识性:一个数据表的所有记录都具有不同的超键 非空性:不能为空 有些时候也把码称作"键" 2.候选键=候选码:能够唯一标识一条记 ...

  5. 【Java】变量

    变量 文章目录 变量 1.变量的概念 2.变量的三要素 3.变量的使用应该注意什么? 4.变量的声明和赋值.使用的语法格式? 5.code 1.变量的概念 变量的作用:变量用来存储数据. 变量的本质: ...

  6. 【Oracle】Oracle中chr()的含义

    oracle中chr含义 CHR(10)和 CHR(13)--在oracle都为换行 chr(32)--表示空格 DECLARE v_a VARCHAR2(255); v_b VARCHAR2(255 ...

  7. ftp设置二进制上传

    一个不重要的数据库,备份是用expdp导出,然后上传到ftp服务器上面.上周这个主机宕机了,要在别的数据库恢复,发现报如下错误: ORA-39001: invalid argument value O ...

  8. 腾讯云COS对象存储占据数据容灾C位

    说到公有云容灾,大家首先想到的是云上数据备份. 然而,随着企业核心业务逐渐从线下迁移到云上,客户提出了更高的要求.如何确保云上业务的高可用.数据的高可靠,这对云厂商提出了新的挑战. 腾讯云作为全球领先 ...

  9. Gulp4.0入门和实战

    gulp4.0入门和实战 我最近遇到需要优化web的性能的任务,然后就捣鼓了一些对资源文件优化压缩的方案.由于之前的项目中有使用到gulp,所以在需要处理的web项目中也优先使用这个技术. 先聊聊gu ...

  10. Linux下利用ifconfig命令查看和操纵网络接口

    为了说明这个问题,首先我们需要解释一下在Linux系统下"网络接口"的含义.通俗来讲,Linux中的所谓网络接口就是指本机的网卡,它相当于计算机的一台负责对网络进行收发数据的外设. ...