首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
SAAS
ToB门户
了解全球最新的ToB事件
论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
微博
Follow
记录
Doing
博客
Blog
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
排行榜
Ranklist
相册
Album
应用中心
qidao123.com ToB IT社区-企服评测·应用市场
»
论坛
›
软件与程序人生
›
后端开发
›
Java
›
偏向锁 10 连问,被问懵圈了。。
返回列表
发新帖
偏向锁 10 连问,被问懵圈了。。
[复制链接]
发表于 2023-2-22 10:30:15
|
显示全部楼层
|
阅读模式
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
×
前言
对于Hotpot JVM中的偏向锁,大部分开发者都比较熟悉或者至少听说过。那我们用下面10个关于偏向锁的进阶问题,检验一下自己离精通还有多远。
如何判断当前锁对象为偏向锁
偏向锁如何判断锁重入
当
代码
运行至synchronized修饰的
代码
块时,符合什么条件才会尝试获取偏向锁
线程进入偏向锁后,会不会创建lock record
偏向锁膨胀后,lock record有什么变化
如何判断当前持有锁的线程已经因为批量重偏向,而被撤销了偏向锁
批量撤销和批量重偏向的触发条件是什么
批量重偏向后,lock record和锁对象有什么变化
批量撤销后,lock record和锁对象有什么变化
批量撤销/重偏向后,新创建的锁对象,是否支持偏向锁
看了上面的问题,如果是胸有成竹,那就可以跳过这篇文章了。如果一脸问号,这篇文章应该对你有所帮助。
名词解释
首先明确下文章中用到的名词,因为不同人可能叫法不一样。
对象头
,Java对象在堆中
存储
时,会按照对象头加实例数据的结构来
存储
。这篇文章只讲锁,所以一般是指对象头中的Markword部分。
klass对象
,jvm在加载类之后,会在堆内存中生成该类的对象,就是我们
代码
中this.getClass()获取的对象。
锁对象
, synchronized指定的锁对象。对于普通方法,这个对象默认是this指针。对于静态方法,锁对象是堆里的class对象。
Lock record
,进入synchronized时在线程栈中生成的锁记录,对这个不熟悉的可以百度一下或看一下《深入java虚拟机》这本书
锁膨胀
,hotspot中从轻量级锁升级成重量级锁称之为膨胀,为了便于理解,通常把偏向锁升级成轻量级锁也称为膨胀。
问题解析
问题1:如何判断当前锁对象为偏向锁
这个问题比较简单,一般了解过对象头或者偏向锁的都比较熟悉。当锁对象为偏向锁时,Markword的偏向锁标识位为1,锁标识位为01。即markword的最后3位为101。
问题2:偏向锁如何判断锁重入
接上面问题的Markword结构,当已经有线程获取到偏向锁,它的id就会填到markword中的线程id中。重入时线程只要检查thread id里存的是否就是自己线程的id就可以了。
问题3:符合什么条件才会尝试获取偏向锁
首先,hotspot中通过参数UseBiasedLocking控制是否启用偏向锁,不设置时默认是启用的。如果想要禁用偏向锁,可以在启动参数中添加-XX:-UseBiasedLocking。
是不是这样回答这个问题就结束了呢?答案是否定的。hotspot还有一个延迟偏向的概念,就是在jvm启动的时候是有一个延迟时间,过了这段时间后偏向锁才开始启用。这个延迟时间通过启动参数BiasedLockingStartupDelay来设置,默认为4秒。那延迟的目的是什么呢?hotspot的解释是在jvm启动过程中,内部有多个逻辑会用到锁,比如类加载。如果一开始就启用偏向锁,就导致频繁的撤销偏向锁,偏向锁的撤销需要在
安全
点执行,这样有可能影响jvm启动的速度。
满足上面2个条件之后,是不是就愉快的进入偏向锁了呢,其实还要经过2关。
第三个条件就是锁对象没有膨胀,如果锁对象已经膨胀成轻量级锁了,那就不会再走偏向锁了。这就是经常说的锁只支持升级,不支持降级。轻量级锁的markword如下:
最后,如果锁对象对应的class发生了批量撤销的动作,也不会再进入偏向锁了。比如有10个锁对象lockobj0..lockobj9,他们都是LockObj类的实例,如果发生偏向锁的批量撤销,那在这10个锁对象上的抢锁操作都不会再走偏向锁逻辑。
问题4:线程进入偏向锁后,会不会创建lock record
了解轻量级锁逻辑的都知道,轻量级锁加锁后,锁对象会保存lock record的引用,关系如下:
那偏向锁有没有呢?答案是有的。其实轻量级锁的这个lock record在运行至synchronized的时候就创建了,这个时候jvm还不知道具体使用的是偏向锁还是轻量级锁,偏向锁和轻量级锁用的是同一个lock record。偏向锁的时候,对象头里没有lock record的指针。
但是,我们再深挖一层,是不是每次都会创建?答案是否定的。比如在同一个方法中,对同一个锁对象的重入,就不会再次创建lock record,比如下面的代码(虽然不会有人这么写代码
回复
使用道具
举报
返回列表
浏览过的版块
Oracle
数据仓库与分析
公有云
人工智能
Mysql
DevOps与敏捷开发
网络安全
分布式数据库
运维.售后
半亩花草
+ 我要发帖
登录后关闭弹窗
登录参与点评抽奖 加入IT实名职场社区
去登录
微信订阅号
微信服务号
微信客服(加群)
H5
小程序
快速回复
返回顶部
返回列表