偏向锁

article/2025/10/4 8:34:17

 

流程讲解

 

当JVM启用了偏向锁模式(JDK6以上默认开启),新创建对象的Mark Word中的Thread Id为0,说明此时处于可偏向但未偏向任何线程,也叫做匿名偏向状态(anonymously biased)。

偏向锁逻辑
1.线程A第一次访问同步块时,先检测对象头Mark Word中的标志位是否为01,依此判断此时对象锁是否处于无所状态或者偏向锁状态(匿名偏向锁);

2.然后判断偏向锁标志位是否为1,如果不是,则进入轻量级锁逻辑(使用CAS竞争锁),如果是,则进入下一步流程;

3.判断是偏向锁时,检查对象头Mark Word中记录的Thread Id是否是当前线程ID,如果是,则表明当前线程已经获得对象锁,以后该线程进入同步块时,不需要CAS进行加锁,只会往当前线程的栈中添加一条Displaced Mark Word为空的Lock Record中,用来统计重入的次数(如图为当对象所处于偏向锁时,当前线程重入3次,线程栈帧中Lock Record记录)。

 

 

 偏向锁重入

退出同步块释放偏向锁时,则依次删除对应Lock Record,但是不会修改对象头中的Thread Id;

注:偏向锁撤销是指在获取偏向锁的过程中因不满足条件导致要将锁对象改为非偏向锁状态,而偏向锁释放是指退出同步块时的过程。

4.如果对象头Mark Word中Thread Id不是当前线程ID,则进行CAS操作,企图将当前线程ID替换进Mark Word。如果当前对象锁状态处于匿名偏向锁状态(可偏向未锁定),则会替换成功(将Mark Word中的Thread id由匿名0改成当前线程ID,在当前线程栈中找到内存地址最高的可用Lock Record,将线程ID存入),获取到锁,执行同步代码块;

5.如果对象锁已经被其他线程占用,则会替换失败,开始进行偏向锁撤销,这也是偏向锁的特点,一旦出现线程竞争,就会撤销偏向锁;

6.偏向锁的撤销需要等待全局安全点(safe point,代表了一个状态,在该状态下所有线程都是暂停的),暂停持有偏向锁的线程,检查持有偏向锁的线程状态(遍历当前JVM的所有线程,如果能找到,则说明偏向的线程还存活),如果线程还存活,则检查线程是否在执行同步代码块中的代码,如果是,则升级为轻量级锁,进行CAS竞争锁;

注:每次进入同步块(即执行monitorenter)的时候都会以从高往低的顺序在栈中找到第一个可用的Lock Record,并设置偏向线程ID;每次解锁(即执行monitorexit)的时候都会从最低的一个Lock Record移除。所以如果能找到对应的Lock Record说明偏向的线程还在执行同步代码块中的代码。

7.如果持有偏向锁的线程未存活,或者持有偏向锁的线程未在执行同步代码块中的代码,则进行校验是否允许重偏向,如果不允许重偏向,则撤销偏向锁,将Mark Word设置为无锁状态(未锁定不可偏向状态),然后升级为轻量级锁,进行CAS竞争锁;

8.如果允许重偏向,设置为匿名偏向锁状态,CAS将偏向锁重新指向线程A(在对象头和线程栈帧的锁记录中存储当前线程ID);

9.唤醒暂停的线程,从安全点继续执行代码。

以上便是偏向锁的整个逻辑了。

延申知识

批量重偏向与批量撤销
渊源:从偏向锁的加锁解锁过程中可看出,当只有一个线程反复进入同步块时,偏向锁带来的性能开销基本可以忽略,但是当有其他线程尝试获得锁时,就需要等到safe point时,再将偏向锁撤销为无锁状态或升级为轻量级,会消耗一定的性能,所以在多线程竞争频繁的情况下,偏向锁不仅不能提高性能,还会导致性能下降。
于是,就有了批量重偏向与批量撤销的机制。

解决场景
批量重偏向(bulk rebias)机制是为了解决:一个线程创建了大量对象并执行了初始的同步操作,后来另一个线程也来将这些对象作为锁对象进行操作,这样会导致大量的偏向锁撤销操作。
批量撤销(bulk revoke)机制是为了解决:在明显多线程竞争剧烈的场景下使用偏向锁是不合适的。

原理
以class为单位,为每个class维护一个偏向锁撤销计数器,每一次该class的对象发生偏向撤销操作时,该计数器+1,当这个值达到重偏向阈值(默认20)时,JVM就认为该class的偏向锁有问题,因此会进行批量重偏向。
每个class对象会有一个对应的epoch字段,每个处于偏向锁状态对象的Mark Word中也有该字段,其初始值为创建该对象时class中的epoch的值。
每次发生批量重偏向时,就将该值+1,同时遍历JVM中所有线程的栈,找到该class所有正处于加锁状态的偏向锁,将其epoch字段改为新值。下次获得锁时,发现当前对象的epoch值和class的epoch不相等,那就算当前已经偏向了其他线程,也不会执行撤销操作,而是直接通过CAS操作将其Mark Word的Thread Id 改成当前线程Id。
当达到重偏向阈值后,假设该class计数器继续增长,当其达到批量撤销的阈值后(默认40),JVM就认为该class的使用场景存在多线程竞争,会标记该class为不可偏向,之后,对于该class的锁,直接走轻量级锁的逻辑。

 

 


http://chatgpt.dhexx.cn/article/AVLXDCMI.shtml

相关文章

什么是间隙锁?

什么是间隙锁? 间隙锁是一个在索引记录之间的间隙上的锁。 间隙锁的作用 保证某个间隙内的数据在锁定情况下不会发生任何变化。比如mysql默认隔离级别下的可重复读(RR)。 当使用唯一索引来搜索唯一行的语句时,不需要间隙锁定。如下面语句的id列有唯一索引,此时只会对id值…

锁消除、锁粗化、偏向锁、适应性锁

文章目录 锁消除锁粗化偏向锁适应性锁 锁消除 锁消除是JIT编译器对内部锁实现的一种优化。JIT可以借助逃逸分析来判断同步块的锁对象是否只是被一个线程访问,如果是的话,则在编译期间不生成内部锁的申请与释放对应的机器码,即消除了锁的使用…

多线程并发之CountDownLatch(闭锁)使用详解

专题相关文章: 从内存可见性看Volatile、原子变量和CAS算法 多线程并发之CountDownLatch(闭锁)使用详解 多线程并发之显示锁Lock与其通信方式Condition源码解读 多线程并发之读写锁(ReentranReadWriteLock&ReadWriteLock)使用详解 多线程并发之线程池Executor与…

【ABAQUS】什么是剪切闭锁?剪切闭锁会导致什么?

“完全积分”是指当单元具有规则形状时,对单元刚度矩阵中的多项式项进行精确积分所需的高斯点数。对于六面体和四边形元素,“规则形状”意味着边缘是直的,并以直角相交,任何边缘节点都位于边缘的中点。 完全积分的线性元素在每个…

电力“五防”闭锁系统

(转载) 电力“五防”闭锁系统 随着电子技术在各个行业领域的飞速发展,电力的“五防”也将发生革命性的转变。现代电力系统规模不断扩大,从而促使电压的等级也得到了进一步提高。为了使电力系统的安全稳定运行能够得以充分保障&am…

【LB-1A 100V电压回路断相闭锁继电器】

系列型号 LB-1A电压回路断相闭锁继电器 LB-1A闭锁继电器 1 用途 LB-1A型电压回路断相闭锁继电器(以下简称继电器)是在交流电压回路断线而可能引起继电保护误动作时,对继电保护进行闭锁。该继电器用于中性点非直接接地系统中。 2 结构与工作原…

间隙锁

一.几个基本概念 行锁:给某一行加的锁间隙锁:就是两个值之间的间隙。为了解决幻读问题,InnoDB 只好引入新的锁,也就是 间隙锁 (Gap Lock)。间隙锁Gap,左右都是开区间,间隙锁行锁合称next-key lock,每个 next-key lock…

闭锁,信号量,栅栏

1. 闭锁(countDownLatch) 1.1. 作用: 相当于一扇门,在闭锁到达结束状态之前,这扇门是关着的,所以的线程都不允许通过,当闭锁到达结束状态,这扇门打开并允许所有的线程通过。在…

visio 2010激活教程

一、下载office2010toolkit.zip 若下载链接失效,手动搜索office2010toolkit http://ys-c.ys168.com/605279628/o4W138W45JIPI5SiuWf5/office2010toolkit.zip二、激活 激活过程中需要关闭office套件

Microsoft Visio Professional 2013 安装步骤

1.打开解压后的文件夹,点击setup.exe安装 2.勾选我接受此协议的条款,继续 3.点击立即安装 4.安装完成,关闭。 5.打开第一步解压的文件夹中破解文件夹,鼠标右键以管理员身份运行 6.点击激活office2013VL 7.激活完成 Microsoft Visi…

激活Visio2013

最近需要用Visio,由于密钥过期了,也不知道怎么重新输密钥,于是网上搜索,终于找到了一个方法。 KMSpico工具,安装完后直接打开点击左边红色按钮就可以了。如图: 最后附上工具链接https://pan.baidu.com/s/1…

机器学习十大算法之-CART分类决策树、回归树和模型树

转载(http://blog.163.com/zhoulili1987619126/blog/static/35308201201542731455261/) Classification And Regression Tree(CART)是决策树的一种,并且是非常重要的决策树,属于Top Ten Machine Learning Algorithm。顾名思义&…

决策树入门以及树模型的参数选择

决策树及树模型的参数选择 决策树的基本概念 在数据结构中树是一个重要的数据结构,这里树被我们根据分支起到一个决策的作用。什么是决策?通俗的说就是判断或者决定,我们引用周志华的西瓜书中的例子:这是一个好瓜吗?当…

gbdt、xgb、lgb决策树模型

目录 1.决策树1.1 CART分类树1.2 CART回归树 2.gbdt3.xgboost4.lightgbm5.模型对比6.参考文献 本文主要对决策树、gbdt、xgboost、lightgbm、catboost进行简述和整理,包括模型原理、优劣性等内容 1.决策树 决策树是一种通过对历史数据进行测算,对新数据…

树模型与线性模型的融合模型(Python实现)

目录 一、树模型与线性模型的融合模型 二、Python sklearn实现GBDTLR融合模型 一、树模型与线性模型的融合模型 树模型GBDT原理:https://blog.csdn.net/woniu201411/article/details/83114226 线性模型LR原理:https://blog.csdn.net/woniu201411/art…

机器学习理论与实战(九)回归树和模型树

前一节的回归是一种全局回归模型,它设定了一个模型,不管是线性还是非线性的模型,然后拟合数据得到参数,现实中会有些数据很复杂,肉眼几乎看不出符合那种模型,因此构建全局的模型就有点不合适。这节介绍的树回归就是为了解决这类问题,它通过构建决策节点把数据数据切分成…

决策树模型

本文代码及数据集来自《Python大数据分析与机器学习商业案例实战》 决策树模型的建树依据主要用到的是基尼系数的概念。基尼系数(gini)用于计算一个系统中的失序现象,即系统的混乱程度。基尼系数越高,系统的混乱程度就越高&#x…

新版HyperMesh的Assemblies中调出下拉菜单查看Component(装配关系模型树)

新版HyperMesh的Assemblies中调出下拉菜单查看Component(装配关系模型树) 从Altair更新的2019版本开始,在Model模型树中找不到Assemblies了,这样导致好多用户一直在用14或者17版本,其实这次更新不是把这个功能取消掉了…

Cesium bim模型加载并与模型树关联(分层加载)

很久都没写文章了,最近实在是太忙了,向各位关注我的小伙伴致个歉! 最近没事儿写了个模型树和模型关联的功能,处理工具是用的cesiumlab。 说明一下为什么要用cesiumlab: 网上现在有很多的模型转换工具,如…

举例讲清楚模型树和回归树的区别

根据上面图中的一个例子,我们来分析下,假设A、B两点是曲线上的噪声点。 模型树的叶子节点是一个分段线性函数[1]。 回归树的叶子节点是取一个区间的平均(一个常数值)。 上述图中AB区间的均值是一个暗点。 所以: 对于节点A而言,模…