JAVA面试题分享十:Synchronized 锁升级过程?

一、前言

Java 1.6 时引入了“偏向锁” 和 “轻量级锁”,级别从低到高依次是 :无锁,偏向锁,轻量级锁,重量级锁。这些状态会随着竞争而升级。下面我们就实操来研究一下升级过程,不过需要一些前提知识

二、对象内存布局

我们都知道对象在堆里存放的,那么它的内部结构是怎样的呢,下面以64为操作系统来说明

首先对象包含对象头,实例数据,对齐填充。

对象头:包含mark word 和 Klass 指针 ,在64位下,mark word 占 8个字节,Klass占8个字节如果对象是数组类型还会有一块标志数组长度的数据是4个字节
实例数据:对象中包含的实例变量,不包括静态变量,静态变量不属于对象
对齐填充:对象的大小都必须是8的整数倍,如果前两者不是8的整数倍就会在这里填充字节,使对象达到8的整数倍

三、具体流程

synchronized用的锁是存在Java对象头里的Mark Word中,锁升级功能主要依赖MarkWord中锁标志位和释放偏向锁标志位

  • 偏向锁:MarkWord存储的是偏向的线程ID
  • 轻量锁:MarkWord存储的是指向线程栈中Lock Record的指针
  • 重量锁:MarkWord存储的是指向堆中的monitor对象的指针

 

  • 将锁信息放入对象头中
  • 开始时是乐观锁, 如果锁冲突频繁, 就转换为悲观锁.
  • 开始是轻量级锁实现, 如果锁被持有的时间较长, 就转换成重量级锁.
  • 实现轻量级锁的时候大概率用到的自旋锁策略
  • 是一种不公平锁
  • 是一种可重入锁
  • 不是读写锁

引入对象头后synchronized的重量级锁流程

 

四、阶段介绍

1、轻量级锁

轻量级锁的使用场景:如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化。
轻量级锁:多线程竞争,但是任意时刻最多只有一个线程竞争,即不存在锁竞争太过激烈的情况,也就没有线程阻寨

主要作用

  • 有线程来参与锁的竞争,但是获取锁的冲突时间极短
  • 本质就是自选锁CAS
  • 创建锁记录(Lock Record)对象,每个线程都的栈帧都会包含一个锁记录的结构,内部可以存储锁定对象的Mark Word

2、偏向锁

当线程A第一次竞争到锁时,通过修改Mark Word中的偏向ID、偏向模式。如果不存在其他线程竞争,那么持有偏向锁的线程将永远不需要进行同步。

主要作用
当一段同步代码一直被同一个线程多次访问,由于只有一个线程访问那么该线程在后续访问时便会自动获得锁。

  • 轻量级锁在没有竞争时(就自己这个线程),每次重入仍然需要执行 CAS 操作。
  • Java 6 中引入了偏向锁来做进一步优化:只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word 头,之后发现这个线程 ID 是自己的就表示没有竞争,不用重新 CAS。以后只要不发生竞争,这个对象就归该线程所有
  • 如果是轻量级锁,就算是同一个线程,也会生成对应的Lock Record,和对应的对象的Mard Word进行CAS操作,只是CAS不成功;CAS的原子性实际上是CPU实现的, 其实在这一点上还是有排他锁的,只是比起用重量级锁(Monitor->Mutex Lock), 这里的排他时间要短的多
  • 只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word 头,之后发现这个线程 ID 是自己的就表示没有竞争,不用重新 CAS。以后只要不发生竞争,这个对象就归该线程所有
     

五、总结 

Synchronized锁的升级过程主要包括以下几个阶段:

  1. 无锁状态:初始状态下,对象没有被任何线程锁定,所有的线程都可以尝试获取锁。
  2. 偏向锁状态:当线程第一次获取锁时,对象头中的标记位会变为偏向锁状态,同时记录获取锁的线程ID。此后,如果该线程再次进入同步块,JVM会检查对象头的Mark Word是否指向当前线程的线程ID,如果是,则无需使用CAS操作加锁,直接进入同步块,这就是偏向锁的支持重入的特性。这个过程中并不会涉及到锁的升级。
  3. 轻量级锁状态:当另一个线程尝试获取这个已经被偏向的锁时,偏向锁就会升级为轻量级锁。此时,JVM会通过自旋锁的方式尝试获取锁,自旋就是不会立即阻塞线程,而是让线程空转等待锁释放。如果自旋成功则获取锁,执行同步块;如果自旋失败,则锁升级为重量级锁。
  4. 重量级锁状态:在这个状态下,未抢到锁的线程都会被阻塞,等待操作系统唤醒。此时的性能开销最大,因为线程的阻塞和唤醒都需要操作系统来协助完成。

Synchronized锁的升级过程是为了在保证线程安全的前提下,尽可能地提高程序的性能。通过锁的升级,可以实现在线程竞争不激烈的情况下使用效率更高的锁,而在线程竞争激烈的情况下使用更稳定的锁,从而在各种场景下都能保持较好的性能。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之乎者也·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值