从ReentrantLock实现非公平锁的源码理解AQS中的CLH队列
虽然前面也看过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队列的更多相关文章
- ReentrantLock获取到非公平锁的源码
/** * Performs lock. Try immediate barge, backing up to normal * acquire on failure. */ final void l ...
- 基于ReentrantLock的非公平锁理解AQS
AQS AQS概述 AbstractQueuedSynchronizer抽象队列同步器简称AQS,它是实现同步器的基础组件,juc下面Lock的实现以及一些并发工具类就是通过AQS来实现的,这里我 ...
- ReentrantLock之非公平锁源码分析
本文分析的ReentrantLock所对应的Java版本为JDK8. 在阅读本文前,读者应该知道什么是CAS.自旋. 由于ReentrantLock的公平锁和非公平锁中有许多共同代码,本文只会对这两种 ...
- 源码解析C#中PriorityQueue(优先级队列)的实现
前言 前段时间看到有大佬对.net 6.0新出的PriorityQueue(优先级队列)数据结构做了解析,但是没有源码分析,所以本着探究源码的心态,看了看并分享出来.它不像普通队列先进先出(FIFO) ...
- ReentrantLock源码探究1:非公平锁的获取和释放
1.AQS简单介绍 Sync是ReentrantLock的一个内部类,它继承了AbstractQueuedSynchronizer,即AQS,在CountDownLatch.FutureTask. ...
- 深入了解ReentrantLock中的公平锁和非公平锁的加锁机制
ReentrantLock和synchronized一样都是实现线程同步,但是像比synchronized它更加灵活.强大.增加了轮询.超时.中断等高级功能,可以更加精细化的控制线程同步,它是基于AQ ...
- ReentrantLock 非公平锁不公平在哪
重入锁关键地带: 1:使用unsafe的cas方式对AQS中的state成员变量进行“原子加一”操作. 2:如果当前线程多次lock,相当于对state在原有值基础上继续加一操作:释放锁的条件为“原子 ...
- lesson3.1:java公平锁和非公平锁及读写锁
关于这四种锁的各自情况,网上有很多文章做了介绍,本不想单独开章节介绍,本章只介绍这四种锁的一些源码特点及注意事项. demo 源码:https://github.com/mantuliu/javaAd ...
- Java并发指南8:AQS中的公平锁与非公平锁,Condtion
一行一行源码分析清楚 AbstractQueuedSynchronizer (二) 转自https://www.javadoop.com/post/AbstractQueuedSynchronizer ...
随机推荐
- Salesforce 大数据量处理篇(一)Skinny Table
本篇参考:https://developer.salesforce.com/docs/atlas.en-us.salesforce_large_data_volumes_bp.meta/salesfo ...
- 2018年第九届蓝桥杯B组(201806-----递增三元组)
给定三个整数数组 A = [A1, A2, - AN], B = [B1, B2, - BN], C = [C1, C2, - CN], 请你统计有多少个三元组(i, j, k) 满足: 1 < ...
- instanceof和isInstance的区别
instanceof 是一个操作符(类似new, ==等) ( Object reference variable ) instanceof (class/interface type) if(a i ...
- Command3
压缩和解压 gzip gunzip .gz 指定文件必须带后缀 gzip file filename.gz zip unzip .zip unzip filename.zip directory zi ...
- 数据库表空间收缩之pg_squeeze,pg_repack
数据库表空间收缩之pg_squeeze,pg_repack 目录 数据库表空间收缩之pg_squeeze,pg_repack pg_squeeze1.2 原理 优点 安装 使用 pgstattuple ...
- Syn_Flood攻击&防御手段
Syn_Flood攻击原理 攻击者首先伪造地址对服务器发起SYN请求(我可以建立连接吗?),服务器就会回应一个ACK+SYN(可以+请确认).而真实的IP会认为,我没有发送请求,不作回应.服务器没有收 ...
- 十八般武艺玩转GaussDB(DWS)性能调优:路径干预
摘要:路径生成是表关联方式确定的主要阶段,本文介绍了几个影响路径生成的要素:cost_param, scan方式,join方式,stream方式,并从原理上分析如何干预路径的生成. 一.cost模型选 ...
- 【栈和队列】5、队列概述与数组队列的基本实现 - Java
3-5 数组队列 简单记录 - bobo老师的玩转算法系列–玩转数据结构 - 栈和队列 队列Queue 队列也是一种线性结构 相比数组,队列对应的操作是数组的子集 只能从一端(队尾)添加元素,只能从另 ...
- 【Jboss】一台服务器上如何部署多个jboss
一台服务器上如何部署多个jboss呢?直接把整个部署环境copy一份到相应的目录下? 这样只是前提,但是启动复制后的jboss就会发现,有很多端口被占用 3873,8080,8009,8443,808 ...
- 【ASM】查看ASM磁盘组剩余容量和总容量
col total_size for a10; col free_size for a20; select name,total_mb/1024 || 'G' as total_size , free ...