JAVA并发编程ReentrantLock核心原理剖析

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文介绍了Java并发编程中ReentrantLock的重要性和优势,详细解析了其原理及源码实现。ReentrantLock作为一种可重入锁,弥补了synchronized的不足,如支持公平锁与非公平锁、响应中断等。文章通过源码分析,展示了ReentrantLock如何基于AQS实现公平锁和非公平锁,并解释了两者的具体实现过程。

JAVA并发编程系列以及陆续出了5篇,第六篇的主角ReentrantLock该出场了。之前《一文看懂全部锁机制》谈到可重入锁、《JAVA并发编程AQS原理剖析》谈到了JUC灵魂AQS,那么AQS的思想优秀实践者ReentrantLock是怎么实现AQS的呢?

1、ReentrantLock是什么,有哪些优点

    ReentrantLock英文翻译以及顾名思义:可重入锁。之前文章说过,还有synchronized也是可重入锁。竟然JDK最开始有了synchronized这个可重入锁,而且JDK1.6之后也对synchronized进行锁优化,性能堪比JUC里的其他Lock()。为什么还提供了ReentrantLock呢?在《JAVA并发编程volatile核心原理》文中开头我们就简单的列了synchronized的几个缺点,包括:阻塞时间过长,不可中断、是非公平锁。

所以,同样是可重入锁,ReentrantLock必须有一些亮点。它的优点就是较好的补足synchronized的缺点,提供了非常灵活多变的特性,满足系统项目研发的需求。


     优点有:

     1、支持公平锁+非公平锁。(synchronized仅支持非公平锁)

     2、支持响应中断、超时。(synchronized不支持超时)

     3、支持线程尝试获取锁。(synchronized不支持)


2、具体说说ReentrantLock的原理,看过ReentrantLock源码吗


    话说到这份上,好像不看源码不行了。上源码,不要慌,它的核心源码就这几行,先扫一眼:


刚面试官问:具体说说它的原理?


少废话,一句话总结它的原理:ReentrantLock是AQS的具体实现,实现了公平锁和不公平锁。ReentrantLock源码里有三个内部类。


一个是Sync抽象类;sync 继承了AQS 队列同步器。所以ReentrantLock是AQS的实现。

一个是FailSync类,实现了Sync类,实现的是公平锁。

一个是NonFairSync类,也是实现Sync类,实现的是非公平锁。


“好家伙,总结的还不错”面试官心嘀咕着,继续问:


2.1 公平锁是怎么实现的?

    我们直接看源码,公平锁的lock加锁是acquire(1)方法。

接下来源码是,就看到这里就很清晰了。

public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }


首先,公平锁加锁可能有三部逻辑执行。

第一步:tryAcquire(1),尝试去获取锁。如果成功了,就没有后面两个步骤的事。

第二步:如果第一步获取失败,把当前线程封装为独占锁类型NODE 进入AQS 的FIFO 队列,等待被按顺序唤醒。

第三步:第二步执行后,也会调用selfInterrupt(),里面的源码就是线程自我中断,修改中断标识位为:true。



那具体再说说第一步tryAcquire(1),是如何获取线程锁的?(候选人内心有点破防:面试官问题咋那么多...)


具体就是:

1、先判断当前AQS队列的state是否为0,如果是0,说明现在可以竞争锁。

2、接下来继续判断AQS的同步队列,如果队列是空、或者队列不为空且队列里的节点是不是自己,就去竞争锁。

3、如果竞争锁成功,通过CAS去设置AQS的state值为1,并帮AQS的当前占有锁的NODE 引用线程改完自己。


源码如下:

2.2 非公平锁又是怎么实现的?

   new ReentrantLock()默认的就是非公平锁。

public ReentrantLock() {
        sync = new NonfairSync();
    }


非公平锁的竞争锁就比较暴力,上来就直接通过CAS去竞争,

如果获取失败,进入acquire(1),继续去尝试获取锁。

这里和公平锁也是不一样,它没有判断队列情况,继续用CAS方式去看能否修改state获取锁。


如果竞争失败,就会进入AQS队列,等待被唤醒....

今天暂时分享到这,其实可重入锁里面的源码还有很多内容,篇幅有限,等源码专区出来再全部分享。

相关文章
|
2天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
28天前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19257 29
|
29天前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18797 20
|
28天前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17504 13
Apache Paimon V0.9最新进展
|
30天前
|
存储 人工智能 前端开发
AI 网关零代码解决 AI 幻觉问题
本文主要介绍了 AI Agent 的背景,概念,探讨了 AI Agent 网关插件的使用方法,效果以及实现原理。
18692 15
|
28天前
|
人工智能 自然语言处理 搜索推荐
评测:AI客服接入钉钉与微信的对比分析
【8月更文第22天】随着人工智能技术的发展,越来越多的企业开始尝试将AI客服集成到自己的业务流程中。本文将基于《10分钟构建AI客服并应用到网站、钉钉或微信中》的解决方案,详细评测AI客服在钉钉和微信中的接入流程及实际应用效果,并结合个人体验分享一些心得。
9905 9
|
1月前
|
消息中间件 弹性计算 关系型数据库
函数计算驱动多媒体文件处理解决方案体验评测
从整体解读到部署体验,多方位带你了解如何利用函数计算驱动多媒体文件处理,告别资源瓶颈。
10441 13
|
22天前
|
存储 JSON Serverless
西游再现,函数计算一键部署 Flux 超写实文生图模型部署
参与体验活动生成西游人物图像,既有机会赢取好礼!本次实验在函数计算中内置了flux.1-dev-fp8大模型,通过函数计算+Serverless应用中心一键部署Flux模型,快速生成超写实图像。首次开通用户可领取免费试用额度,部署过程简单高效。完成部署后,您可以通过修改提示词生成各种风格的图像,体验Flux模型的强大绘图能力。
西游再现,函数计算一键部署 Flux 超写实文生图模型部署
|
1月前
|
SQL 容灾 关系型数据库
让X不断延伸, 从跨AZ到跨Region再到跨Cloud
本文从“空间”这一维度,聊一聊PolarDB-X在跨空间部署能力上的不断发展和延伸,以及在不同空间范围下的高可用和容灾能力,并着重介绍一下最新的产品能力——GDN(Global Database Network)。
|
1月前
|
缓存 测试技术 调度
PolarDB-X的TPC-H列存执行计划
本文从官方的角度逐条解析PolarDB-X在TPC-H列存执行计划的设计要点。这些要点不仅包含了各项优化的原理,还提供了相关的证明与代码实现,希望帮助读者更深入地理解PolarDB-X的列存优化器。
7872 11