【Java reentrantlock源码解读】

今天学习一下Java中lock的实现方式aqs

直接上图这是lock方法的实现类、分为公平锁和非公平锁两种。
在这里插入图片描述
先看非公平的实现方法、很暴力有木有,上来直接CAS(抢占锁的方法,是一个原子操作,没有学过的同学自行百度哦),如果抢占失败进入else方法,
在这里插入图片描述

这是else方法,进行了双&&短路运算符操作,咱们先从方法名去猜一猜,tryAcquire()这个方法应该是尝试去获取,如果返回false也就是获取不到才会去执行后面的acquireQueued(),看到这个queue我就联想到了aqs的数据结构双向等待队列。这些都是猜想,咱们继续看代码。
在这里插入图片描述
在这里插入图片描述

咱们接着看源码,这就是尝试获取锁调用的代码(非公平锁,公平锁等会看),if(c==0)表示锁未被占领然后就开始获取锁,获取成功返回true。else if表示当前获取锁的线程和持有锁的线程相等了,没错,这就是可重入锁了(可重入锁的好处就是不会发生死锁)。
在这里插入图片描述
综上所述,非公平锁是这么干的:首先上来直接获取锁(cas),如果获取不到发现当前锁没有被占领(if(c == 0))再次获取锁。
接着看公平锁是怎么干的。

并没有像非公平锁那样上来直接cas,温柔了很多。
在这里插入图片描述

公平锁同样分为两种情况,当c == 0表示当前锁没有被占领,公平锁比非公平锁多了hasQueuedPredecessors(),我猜这个方法是判断等待队列中是否存在节点,如果有节点就要遵循公平原则,没有节点才能cas去抢占,接下来看代码。
在这里插入图片描述

若 h == t则队列为空,直接返回false就会进入到抢占锁的代码中,咱们的猜测是正确的。
在这里插入图片描述

也就是说公平锁并没有像非公平锁一样一上来就抢占锁,也没有像非公平锁那样发现锁没有被占有就直接去抢占,而是先判断一下等待队列中还有没有其他线程。

看到这儿已经明白了公平锁和非公平锁是如何获取锁的,大家可以稍作休息,接下来接着看获取失败后是如何进入等待队列的,进入队列后又是如何再次获取锁的。

在这里插入图片描述
咱们先看addWaiter()方法,然后看acquireQueued(),大神写的代码太紧凑了。。。

首先创建了一个node节点包含当前线程,然后获取了尾部节点,如果尾部节点不为空,就尝试把该节点放到尾部。如果添加到尾部失败了就会进入enq()方法。我们接着看。
在这里插入图片描述

哈哈,一上来就是一个自旋,也就是说上一步的加入尾部顺利的话是不需要进入自旋的。
我们接着看自旋里干了什么,首先获取尾部节点,如果为空的话就初始化了头节点,并且将尾部节点指向头节点。
思考:也就说这个等待队列是在获取锁的时候才初始化的,对吧!并且初始化的队列是尾指向头的一个空节点(不包含线程信息new Node()构造函数没有传递任何内容)。
好,我们接着看代码,如果 t != null,就把当前节点设置为尾巴节点。
思考:为什么要自旋呢,一是为了初始化这个等待队列,二就涉及到了线程安全问题,这个队列是一个多条线程共享的资源,怎么保证线程安全问题呢,没错这儿的初始化队列方法和入队方法都是调用的保障线程安全的方法,即使发生了竞争导致失败了,依旧自旋继续尝试!总之最终要保证这个节点加入到等待队列中!
思考:如果是公平锁在加入等待队列的途中,发生了多条线程的竞争,会不会出现不公平的情况呢?
在这里插入图片描述

我们接着来看看acquireQueued(),继上一步的自旋成功入队以后,哈哈又开始自旋了,我们接着看自旋里做了什么。
node.predecessor()获取了当前节点的前一个节点,如果前一个节点是头节点就去抢占锁,(等待队列是一个双向fifo队列,并且头节点为空,这里的为空指的是node中的thread为null,setHead方法中体现)
思考:也就说抢占到锁的node不在等待队列中,排队最靠前的node在第二个节点,头节点永远是空的,没问题吧!

在这里插入图片描述
我们接着看shouldParkAfterFailedAcquire()和 parkAndCheckInterrupt()干了什么,需要注意的地方时这个if和上面的if是同级的,也就是说每次自旋都会反复执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/17144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MagicaCloth2中文文档

提示:经搬运者测试,在ecs1.0中运行最为良好 如何安装 英语日语 目录 [隐藏] 1 如何安装2 样本运行测试3 可以删除示例文件夹4 如何更新5 发生错误时该怎么办6 如何卸载7 如何检查版本 如何安装 MagicaCloth2 需要 Unity 2021.3.16 (LTS&…

jQuery效果2

jQuery 一、属性操作1.内容2.列子,购物车模块-全选 二、内容文本值1.内容2.列子,增减商品和小记 三、元素操作(遍历,创建,删除,添加)1.遍历2.例子,购物车模块,计算总件数和总额3.创建…

【简单介绍下线性回归模型】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

Habicht定理中有关子结式命题3.4.6的证明

个人认为红色区域有问题,因为 deg ⁡ ( ϕ ( S j ) ) r \deg{\left( \phi\left( S_{j} \right) \right) r} deg(ϕ(Sj​))r,当 i ≥ r i \geq r i≥r时, s u b r e s i ( ϕ ( S j 1 ) , ϕ ( S j ) ) subres_{i}\left( \phi(S_{j 1}),\p…

函数调用时长的关键点:揭秘参数位置的秘密

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、默认参数的秘密 示例代码 二、关键字参数与位置参数的舞蹈 示例代码 总结 一、默认参…

PyCharm面板ctrl+鼠标滚轮放大缩小代码

1.【File】➡【Settings】 2.点击【Keymap】,在右边搜索框中搜incre,双击出现的【Increase Font Size】 3.在弹出的提示框中选择【Add Mouse Shortcut】 4.弹出下面的提示框后,键盘按住【ctrl】,并且上滑鼠标滚轮。然后点击【O…

ResizeObserver loop completed with undelivered notifications.

报错信息 ResizeObserver loop completed with undelivered notifications. 来源 在用vue3 element-plus写项目的时候报的错,经过排查法,发现是element-plus的el-table组件引起的错误。 经过初步排查,这个错误并不是vue以及element-plus…

Redis数据类型(上篇)

前提:(key代表键) Redis常用的命令 命令作用keys *查看当前库所有的keyexists key判断某个key是否存在type key查看key是什么类型del key 删除指定的keyunlink key非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的…

vueRouter路由总结

https://blog.csdn.net/qq_24767091/article/details/119326884

中国电子节能技术协会数据安全专业委员会筹备会暨标准征集启动会即将开幕

导读:“以高效、安全、绿色数据底座铸就美好未来”为主题的2024数据安全与绿色发展研讨会,中国电子节能技术协会数据安全专业委员会筹备会暨标准征集启动会即将开幕。 绿色发展是高质量发展的底座,绿色化是新一轮科技革命和产业变革的重要趋势…

Oracle数据库Day01-SELECT语句

一、SQL语句 1. 环境配置与准备 linux端oracle用户打开监听//查看监听状态与开始监听 lsnrctl status lsnrctl start开启数据库sqlplus / as sysdba startup;解锁hr用户样例数据库,给hr用户设置密码并且连接alter user hr account unlock; alter user hr identifie…

2024爆款神器!会声会影2024旗舰版,让你的视频制作技能暴涨,不学真的亏大了!

在数字内容创作的时代,视频编辑已经成为连接创意与现实的重要桥梁。无论是个人Vlog制作、在线教育课程、企业宣传还是专业影视制作,高效而强大的视频编辑软件成为了必不可少的工具。会声会影2024旗舰版,作为一款集先进技术与用户友好界面设计…

常用API(正则表达式、爬取、捕获分组和非捕获分组 )

1、正则表达式 练习——先爽一下正则表达式 正则表达式可以校验字符串是否满足一定的规则,并用来校验数据格式的合法性。 需求:假如现在要求校验一个qq号码是否正确。 规则:6位及20位之内,0不能在开头,必须全部是数字…

30.哀家要长脑子了!---栈与队列

1.388. 文件的最长绝对路径 - 力扣(LeetCode) 其实看懂了就还好 用一个栈来保存所遍历过最大的文件的绝对路径的长度,栈顶元素是文件的长度,栈中元素的个数是该文件目录的深度,非栈顶元素就是当时目录的长度 检查此…

Qt 5前后调色板差异变化

Qt 5之前: QPalette palette;//调色板 设置背景颜色 palette.setColor(QPalette::Backgound, color...);Qt 5之后: 由原有的 Background 模式 更新为 Window 模式 QPalette palette;//调色板 设置背景颜色 palette.setColor(QPalette::Window, color..…

10.SpringBoot 统一处理功能

文章目录 1.拦截器1.1在代码中的应用1.1.1定义拦截器1.1.2注册配置拦截器 1.2拦截器的作用1.3拦截器的实现 2.统一数据返回格式2.1 为什么需要统⼀数据返回格式?2.2 统⼀数据返回格式的实现 3.统一异常处理4.SpringBoot专业版创建项目无Java8版本怎么办?…

nodejs安装配置

nodejs安装 打开nodejs官网(https://nodejs.org/en/download/package-manager),参考安装步骤操作。 更新镜像源 输入以下命令,将npm的镜像源设置为淘宝镜像。网上资料中,淘宝镜像地址多为https://registry.npm.taobao.org,这个…

【MATLAB源码-第67期】基于麻雀搜索算法(SSA)的无人机三维地图路径规划,输出最短路径和适应度曲线。

操作环境: MATLAB 2022a 1、算法描述 麻雀搜索算法(Sparrow Search Algorithm, SSA)是一种新颖的元启发式优化算法,它受到麻雀社会行为的启发。这种算法通过模拟麻雀的食物搜索行为和逃避天敌的策略来解决优化问题。SSA通过模拟…

【C++】:vector容器的基本使用

目录 🍒1,vector的介绍🍒2,vector的使用🐯2.1 vector的构造🦁2.2 vector iterator 的使用🌽2.3 vector 空间增长问题🍓2.4 vector 增删查改🐯2.5 vector 访问及遍历&…

雷军-2022.8小米创业思考-9-爆品模式:产品力超群,具有一流口碑,最终实现海量长销的产品。人人都向往;做减法;重组创新;小白模式

第九章 爆品模式 小米方法论的第三个关键词,就是一切以产品为出发点,打造爆品模式。 大多数人对“爆品”的着眼点仅在于“爆”,也就是产品卖得好。希望产品大卖这没有错,但是“爆”是“品”的结果,爆品是打造出来的&…