synchronized 锁升级详解

synchronized 初步认识传送门:

synchronized 使用及深入理解

什么是锁?

锁是一种用于控制对共享资源访问的机制,它可以确保在某个时刻只有一个线程或进程可以访问被锁定的资源,从而保证数据的一致性和安全性。在计算机科学中,锁常用于并发编程,以解决多线程或多个进程并发访问共享资源时可能出现的数据竞争和不一致性问题。

synchronized 锁标记在哪里?

前文说了 synchronized 的实现原理是依赖于 JVM 实现的,锁跟 monitor 相关,而 monitor 的实现依赖于操作系统和互斥锁的实现,效率比较低,而锁的状态一共有四种:无锁、偏向锁、轻量级锁和重量级锁,记录锁状态的标记是在对象头的 Mark Word中(一个对象的结构分为对象头、实际存放的数据和补齐位),锁标记情况如下:

在这里插入图片描述

什么是锁升级?

锁升级是指将多个细粒度锁转换为粗粒度锁的过程,叫做锁升级,需要注意的锁只会升级不会降级,锁一旦升级到更高级别,就不会再回到低级别。

锁升级涉及到哪些锁概念?

  • 偏向锁(只有一个线程进入临界区):发生在单线程的情况下,从偏向二字就可以知道,锁一直是偏向某个线程的,偏向锁是为了减少无竞争情况的下的锁竞争开销,当线程访问同步代码获取锁的时候,会将锁标志记录在线程的栈帧中,并将把 monitor 对象头中的线程 id 设置为当前线程 id,后续当前线程再次请求同一个锁的时候,会直接使用已经标记的锁记录,不需要再次进行加锁解锁,以高并发性能。
  • 轻量级锁(多个线程交替进入临界区):轻量级锁是JDK1.6之中加入的新型锁机制,当偏向锁被撤销,或其他线程竞争的时候,偏向锁会撤销并且升级为轻量级锁,轻量级锁使用CAS操作来实现锁的获取和释放,避免了线程的阻塞和唤醒,从而提高了并发性能。
  • 重量级锁(多个线程同时进入临界区):重量级锁在JVM中有一个监视器 monitor,内部又两个队列,锁竞争队列和信号阻塞队列,一个实现线程互斥,另一个实现线程同步,重量级锁在底层是靠操作系统的Mutex Lock实现的,线程在阻塞和唤醒状态间切换需要操作系统将线程在用户态与核心态之间转换,成本很高,所以重量级锁的效率不高。

锁升级过程

无锁–>偏向锁–>轻量级锁–>重量级锁

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6f5cbcf8db9a4619885d20716389d89a.png

锁升级流程解释:

  • 最开始是无锁状态,此时第一个线程进来了,因为是无锁状态,直接就锁升级为偏向锁,并将使用 CAS 将当前线程 id 设置到到 Mark Word 中,然后开始执行同步代码。
  • 此时第二个线程进来,先去偏向锁指向的线程 id 是否是自己,如果是自己,获得偏向锁,如果不是,尝试使用 CAS 修改 Mark Word 中的线程 id 指向自己,成功则获取偏向锁(前面线程释放锁了),如果没有成功(前面线程没有释放锁),则 JVM 会在第一个线程到达安全点的时候撤销当前的偏向锁,然后会给当前线程栈中会分配锁记录,并拷贝 Mark Word 到锁记录中,做好这些之后,两个线程同时 CAS 的方式去修改 Mark Word 中的指针指向自己,谁修改成功了,就将锁升级为轻量级锁,去执行同步代码,修改失败了,就继续 CAS 自旋。
  • CAS 修改失败线程会进入自旋状态,自旋(自适应自旋)到 JVM 设定的次数(JVM 进行调整)后结束,此时 JVM 将锁状态升级为重量级锁,将 Mark Word 指向重量级锁 Monitor 的指针,然后挂起线程(放在Monitor的 EntryList中),前面获取轻量级锁的线程执行完毕后,会判断当前 Mark Word 中的指针是否仍然指向自己,是的话就释放锁,否则就说明此时已经升级成了重量级锁,这时候除了释放锁之外,还需要唤醒阻塞的线程,被唤醒的线程进行新一轮的重量级锁竞争。

为什么要有锁升级过程?

  • 减少无竞争情况下的锁开销,偏向锁通过记录线程 id 来避免加锁和解锁操作,提高了单线程访问同步代码块的性能,。
  • 避免线程切换带来的开销,轻量级锁的自旋操作就是为了减少线程切换带来的开销,如果竞争锁成功就开始执行同步代码,执锁竞争失败就开始自旋,等待锁释放,避免线程切换带来的开销。
  • 提高系统的性能,所有的措施都是为了提升系统性能,锁升级也不列外,锁升级操作是为了提高多线程环境下的性能。

如有错误的地方欢迎指出纠正。

  • 51
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值