虽然前面也看过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. 买卖股票的最佳时机 III

    给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 两笔 交易. 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的 ...

  2. Go语言从入门到放弃(结构体常见的tag)

    什么是tag Tag是结构体中某个字段别名, 可以定义多个, 空格分隔 type Student struct {     Name string `ak:"av" bk:&quo ...

  3. js原型链原理

    先附上原型链的图,能看懂的本文就没必要看了,看不懂的可以带着疑问看文章 一.构造函数 什么是构造函数:当一个普通函数创建一个类对象是,那么就程它为构造函数. 特点: 默认首字母大写 使用new关键字来 ...

  4. Macbook 安装Windows的完美教程

    [原文](http://www.melodydance.top/mac-win.html) 1. 背景 Windows相对于Mac市场占有率更高,对很多人来说Windows使用起来更方便,以至于很多人 ...

  5. iTerm2 实现 ssh 自动登录,并使用 Zmodem 实现快速传输文件

    原文链接:https://fuckcloudnative.io/posts/iterm2-auto-login/ 对于 YAML 工程师来说,我们经常需要 ssh 登录不同的服务器,每次登录时都要经历 ...

  6. VBA实现相同行合并

    帮人捣鼓了个VBA代码用来实现多行合并,具体需求为:列2/列3/列4 相同的情况下,则对应的行合并为一行,且列1用空格隔开,列5则相加: (对大多数办公室职员,VBA还算是提高效率的一个利器吧) 最终 ...

  7. 【Zabbix】配置zabbix agent向多个server发送数据

    1.背景: server端: 172.16.59.197  ,172.16.59.98 agent 端: hostname:dba-test-hzj02 IP:172.16.59.98 2.方式: 配 ...

  8. ctfhub技能树—web前置技能—http协议—Cookie

    打开靶机环境 查看显示内容 根据提示,需要admin登录才能得到flag 题目介绍为Cookie欺骗.认证.伪造 介绍一下cookie和session 一.cookie: 在网站中,http请求是无状 ...

  9. 强制删除 Terminating 状态的pod

    [root@k8s-master coredns]# kubectl get podNAME                     READY   STATUS        RESTARTS   ...

  10. Vijos-P1103题解【线段树】

    本文为原创,转载请注明:http://www.cnblogs.com/kylewilson/ 题目出处: https://www.vijos.org/p/1103 题目描述: 一条马路从数轴0到L,每 ...