synchronized的偏向锁、轻量级锁和重量级锁
文章目录
- Java对象头
- 偏向锁
- 批量重偏向
- 批量撤销
- 轻量级锁
- 重量级锁
- Monitor 原理
Java对象头
普通对象
Mark Word在64 位虚拟机中的结构为
Mark Word后三(两)位表示
- 001:无锁状态
- 101: 偏向锁
- 00: 轻量级锁
- 10:重量级锁
偏向锁
Jdk6开始,默认开启偏向锁。当线程获取锁资源时,只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word
头,之后发现这个线程 ID 是自己的就表示没有竞争,不用重新 CAS。以后只要不发生竞争,这个对象就归该线程所有。
- 当锁释放之后,另一线程获得锁资源,则偏向锁升级为轻量级锁。
- 若锁还未释放,另一线程就来竞争锁资源,则偏向锁直接升级为重量级锁。
- 调用
wait/notify
方法时,偏向锁直接升级为重量级锁,因为只有重量级锁才有该方法。 - 调用
hashcode
方法,因为没有空间存储hashcode
,偏向锁自动撤销,变为无锁状态。
批量重偏向
如果一个类的大量对象被一个线程T1执行了同步操作,也就是大量对象先偏向了T1,T1同步结束后,另一个线程也将这些对象作为锁对象进行操作,会导偏向锁重偏向的操作。
BiasedLockingBulkRebiasThreshold
:偏向锁批量重偏向的默认阀值为20次。
批量撤销
当一个偏向锁如果撤销次数到达40的时候就认为这个对象设计的有问题;那么JVM会把这个对象所对应的类所有的对象都撤销偏向锁;并且新实例化的对象也是不可偏向的。
BiasedLockingBulkRevokeThreshold
:偏向锁批量撤销的默认阀值为40次。
批量重偏向和批量撤销是针对类的优化,和对象无关。偏向锁重偏向一次之后不可再次重偏向。当某个类已经触发批量撤销机制后,JVM会默认当前类产生了严重的问题,剥夺了该类的新实例对象使用偏向锁的权利。
轻量级锁
轻量级锁的使用场景:如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化。
轻量级锁对使用者是透明的,即语法仍然是 synchronized
假设有两个方法同步块,利用同一个对象加锁。
轻量级锁的操作步骤如下:
- 创建锁记录(
Lock Record
)对象,每个线程都的栈帧都会包含一个锁记录的结构,内部可以存储锁定对象的Mark Word
- 让锁记录中
Object reference
指向锁对象,并尝试用 cas 替换 Object 的Mark Word
,将Mark Word
的值存入锁记录。
- 如果 cas 失败,有两种情况
- 如果是其它线程已经持有了该
Object
的轻量级锁,这时表明有竞争,进入锁膨胀过程。 - 如果是自己执行了
synchronized
锁重入,那么再添加一条Lock Record
作为重入的计数。
- 如果是其它线程已经持有了该
- 当退出
synchronized
代码块(解锁时)如果有取值为null
的锁记录,表示有重入,这时重置锁记录,表示重
入计数减一。 - 当退出
synchronized
代码块(解锁时)锁记录的值不为null
,这时使用 cas 将Mark Word
的值恢复给对象头。- 成功,则解锁成功。
- 失败,说明轻量级锁进行了锁膨胀或已经升级为重量级锁,进入重量级锁解锁流程。
重量级锁
Monitor 原理
每个 Java 对象都可以关联一个Monitor
对象,如果使用 synchronized
给对象上锁(重量级)之后,该对象头的
Mark Word
中就被设置指向Monitor
对象的指针。
Monitor 结构如下:
- 刚开始
Monitor
中Owner
为 null。 - 当
Thread-2
执行synchronized(obj)
就会将Monitor
的所有者Owner
置为Thread-2
,Monitor
中只能有一个Owner
。 - 在
Thread-2
上锁的过程中,如果Thread-3
,Thread-4
,Thread-5
也来执行synchronized(obj)
,就会进入
EntryList
BLOCKED。 Thread-2
执行完同步代码块的内容,然后唤醒EntryList
中等待的线程来竞争锁,竞争的时是非公平的。- 图中
WaitSet
中的Thread-0
,Thread-1
是之前获得过锁,但条件不满足进入调用wait()
方法进入 WAITING 状态的线程。当调用notifyAll()
方法之后,WaitSet
中的Thread-0
,Thread-1
进入EntryList
BLOCKED。
synchronized的偏向锁、轻量级锁和重量级锁相关推荐
- 12.synchronized的锁重入、锁消除、锁升级原理?无锁、偏向锁、轻量级锁、自旋、重量级锁
小陈:呼叫老王...... 老王:来了来了,小陈你准备好了吗?今天我们来讲synchronized的锁重入.锁优化.和锁升级的原理 小陈:早就准备好了,我现在都等不及了 老王:那就好,那我们废话不多说 ...
- 操作系统锁的实现方法有哪几种_java 偏向锁、轻量级锁及重量级锁synchronized原理...
Java对象头与Monitor java对象头是实现synchronized的锁对象的基础,synchronized使用的锁对象是存储在Java对象头里的. 对象头包含两部分:Mark Word 和 ...
- java中synchronized锁的升级(偏向锁、轻量级锁及重量级锁)
java同步锁前置知识点 编码中如果使用锁可以使用synchronized关键字,对方法.代码块进行同步加锁 Synchronized同步锁是jvm内置的隐式锁(相对Lock,隐式加锁与释放) Syn ...
- Synchronized偏向锁、轻量级锁、重量级锁详解
一.偏向锁加锁 1.通过CAS操作将当前线程的地址设置到锁对象的markword中.如果设置成功了,那么就是设置偏向锁成功了 2.在当前线程的栈贞中,创建锁记录(Lock Record),使这个锁记录 ...
- Synchronized的原理及自旋锁,偏向锁,轻量级锁,重量级锁的区别
在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,Java S ...
- 简单理解重量级锁、轻量级锁、偏向锁
全文使用synchronized来说明. synchronized给对象上锁,先上偏向锁,在上轻量级锁,最后上重量级锁.上什么锁,是gvm根据竞争程度自行变换的. 重量级锁 计算机操作系统本有Moni ...
- 线程安全(中)--彻底搞懂synchronized(从偏向锁到重量级锁)
接触过线程安全的同学想必都使用过synchronized这个关键字,在java同步代码快中,synchronized的使用方式无非有两个: 通过对一个对象进行加锁来实现同步,如下面代码. synchr ...
- java多线程之锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁
转载至:https://blog.csdn.net/zqz_zqz/article/details/70233767 之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比 ...
- 【Java】什么是CAS、synchronized升级概述、偏向锁/轻量级锁详解 - 笔记
引入 CAS lock cmpxchg在硬件层面实现:在操作过程中不允许被其他CPU打断,避免CAS在写数据的时候被其他线程打断,相比操作系统级别的锁,效率要高很多. 加锁才能让多线程的访问变为序列化 ...
最新文章
- 2022-2028年中国车载天线行业市场前瞻与投资战略规划分析报告
- 两种ICP的改进算法:PLICP与NICP
- transformer详解 大牛 wmathor
- 一道神坑题 POJ3026 Borg Maze BFS+prim算法
- 在线音频“三国争霸”,谁能率先登陆资本市场?
- 1067: 有问题的里程表
- python迭代器_Python迭代器
- 在外键上创建索引V1.0
- oracle虚拟件不活动,BOM 中的虚拟件
- 一个较好的基础的数据库连接池知识
- echart legends换行固定数量显示
- 中介管理系统php源代码,PHP房产中介管理系统小程序源码8.0.5 后台+前端
- ad6怎么画电阻_光敏电阻传感器的使用
- 相信美好就能遇见美好—西安独行三日短途穷游 攻略
- win7修复计算机卡了,Win7修复漏洞补丁后系统变卡的原因和解决方法
- 快捷指令通知运行html,快捷指令通知怎么关?快捷指令通知关了又自动开了的原因...
- 机器学习实战——疫情数据分析与预测
- [ZZ]什么是Google Urchin:了解Urchin与Google Analytics差异
- 刘润、陈果、董小英、朋新宇、付晓岩等50余位专家力荐《精益数据方法论》重磅上市!...
- [光劍藏書館2020] 孔夫子旧书网