前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AQS中的cancelAcquire何时会运行

AQS中的cancelAcquire何时会运行

原创
作者头像
子牙老师
修改2022-05-11 10:11:49
4480
修改2022-05-11 10:11:49
举报
文章被收录于专栏:手写JVM专栏

哈喽,我是子牙。十余年技术生涯,一路披荆斩棘从技术小白到技术总监到JVM专家到创业。技术栈如汇编、C语言、C++、Windows内核、Linux内核。特别喜欢研究虚拟机底层实现,对JVM有深入研究。分享的文章偏硬核,很硬的那种。

手撸过JVM、内存池、垃圾回收算法、synchronized、线程池、NIO、三色标记算法…

今天分享一篇JUC包中AQS的一个方法的深度解读,可能你都没有关注过这个细节吧。

这篇文章适合对AQS有一定基础的童鞋学习。学完本篇文章就可以对AQS高级部分有更深入的理解:比如AQS中的节点什么时候会修改自己的waitStatus、Node._CANCELLED状态有何意义、_cancelAcquire何时会运行……

尤其是cancelAcquire何时会运行,最近讲完AQS课被问得比较多。今天抽个空写篇文章分享下。cancelAcquire这个方法内部做了什么,后面写文章分享,这个方法的代码也很难理解。

国际惯例,先上代码。

这两段代码是AQS的源码,因为AQS被很多类共用,本篇文章是从ReentrantLock角度进行分析。

分析问题

当failed为true时才会执行方法cancelAcquire,那什么情况下failed为true呢?try代码段执行过程中出现异常。

那什么情况下try代码段执行过程中会出现异常呢?整个流程看下来,只有两个地方有可能:predecessor、tryAcquire。看下源码,都会抛出异常。

那真正导致try代码段执行过程中出现异常是因为哪一个呢?我们来逐个分析下。

如果是因为tryAcquire

肯定不可能。为什么这么说呢?看代码

如果tryAcquire没有被重写,程序根本执行不到方法acquireQueued。因为不会有线程拿到锁,不会有线程因抢不到锁入队列。

如果是因为predecessor

其实也不可能。虽然这里有抛出异常的代码,但是这段代码永远不会执行到。所以注释里有这句话。

The null check could be elided, but is present to help the VM

空检查可以省略,但存在是为了帮助VM

为什么说抛出异常那段代码永远不会执行到呢?方法predecessor是入队后执行的,AQS队列有这样的特点:入队后至少有两个节点,第一个节点永远是占有锁的线程对应的节点。

第三种可能

刚刚分析完我们好不容易找到的两条线索,经过缜密的分析,得出结论都不可能。于是有了第三种可能:第二个节点加锁失败,没有机会将failed改为true。有没有可能呢?来分析下

先回答第一个问题:什么时候第二个节点加锁失败呢?答案是非公平锁的时候。即占有锁的线程刚释放完锁,刚唤醒第二个节点或者,这时候恰好来了一个线程拿到了锁,这时候唤醒的第二个节点来抢锁就会抢锁失败。

虽然抢锁失败了,但是也不会执行到finally代码段,而是重新自旋设置闹钟,然后调用park阻塞自己等待再次唤醒。

结论一

你还能想到其他可能吗?我是想不到了。那cancelAcquire永远不会执行吗?

在ReentrantLock中,不管是公平锁还是非公平锁,cancelAcquire都不会运行。那道格李为什么这样写呢?这个有点像编译器编译sync时会生成两个monitorenter,一种保险策略吧。

还有一种可能:有可能是保持代码统一,反正用到的时候会用到,用不到的时候也不会被执行到。有的童鞋可能说,道格李这样的大神不可能犯这种低级错误吧。我倒不觉得这是一种低级错误,保持统一反映了代码洁癖、反映了先有思想后有代码。

结论二

那什么情况下方法cancelAcquire会运行呢?响应中断的程序中,句式如

题外话

子牙手写JVM小班四期招生即将结束。四期新增了字节码增强+Agent,学完你就可以做JVM相关的工作,如二开arthas,自研类hsdb调试器、自研实现热更新热部署零侵入日志等黑科技…

四期完整课程包含七大专题+一个增值专题,约50多个课时。完整学完你就可以:1、用Java写一个Java虚拟机,从而深入理解运行系统的底层细节;2、有能力自行研究Hotspot源码及其他用C语言、C++写的中间件源码;3、能够用C语言、C++写任何你感兴趣的基础算法如:内存池、垃圾回收算法、主从同步算法、执行引擎、存储引擎;4、就有底子跟着我学习下半年准备开的操作系统内核班……

这套课程,横跨多个计算机学科,但只是一个学科的价格。这套课程,JVM专家、功力深厚、经验丰富的子牙老师亲授,跟我学习不踩坑,全网唯一教授虚拟机的课程…

感兴趣小伙伴可以加班班微信咨询(jvm-anan),真诚招生,无任何套路。课程试看,问题真诚解答,全部了解清楚再上车。一二三期共500多VIP加入,无一人退费,好评不断

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分析问题
  • 第三种可能
  • 结论一
  • 结论二
  • 题外话
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档