「Synchronized与锁升级」锁优化的背景及性能的变化

发布于:2022-12-10 ⋅ 阅读:(573) ⋅ 点赞:(0)

Synchronized锁优化的背景

  • 能够实现数据的 安全性 ,但是会带来 性能下降

  • 无锁能够基于线程并行提升程序性能,但是会带来 安全性下降


Synchronized的性能变化

java5以前

只有Synchronized,这个是操作系统级别的重量级操作,重量级锁,假如锁的竞争比较激烈的话,性能下降。

用户态和内核态之间的切换

image-20220921012938628

Java的线程是映射到操作系统原生线程之上的,如果要阻塞或唤醒一个线程就需要操作系统介入,需要在户态与核心态之间切换,这种切换会消耗大量的系统资源,因为用户态与内核态都有各自专用的内存空间,专用的寄存器等,用户态切换至内核态需要传递给许多变量、参数给内核,内核也需要保护好用户态在切换时的一些寄存器值、变量等,以便内核态调用结束后切换回用户态继续工作。

在Java早期版本中, synchronized属于重量级锁,效率低下,因为监视器锁(monitor)是依赖于底层的操作系统Mutex Lock来实现的 ,挂起线程和恢复线程都需要转入内核态去完成,阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态切换需要耗费处理器时间,如果同步代码块中内容过于简单,这种切换的时间可能比用户代码执行的时间还长”,时间成本相对较高,这也是为什么早期的synchronized效率低的原因


为什么每一个对象都可以成为一个锁

  • markOop.hpp

image-20220921235149362

Monitor可以理解为一种同步工具,也可理解为一种同步机制,常常被描述为一个Java对象。 Java对象是天生的Monitor,每一个Java对象都有成为Monitor的潜质,因为在Java的设计中 ,每一个Java对象自打娘胎里出来就带了一把看不见的锁,它叫做内部锁或者Monitor锁

image-20220921235515597

Monitor的本质是依赖于底层操作系统的Mutex Lock实现,操作系统实现线程之间的切换需要从用户态到内核态的转换,成本非常高。

  • Monitor(监视器锁)

Monitor是在jvm底层实现的,底层代码是c++ 。本质是依赖于底层操作系统的Mutex Lock实现,操作系统实现线程之间的切换需要从用户态到内核态的转换,状态转换需要耗费很多的处理器时间成本非常高。 所以synchronized是Java语言中的一个重量级操作


Monitor与Java对象以及线程是如何关联 ?

1.如果一个java对象被某个线程锁住,则该java对象的Mark Word字段中LockWord指向monitor的起始地址

2.Monitor的Owner字段会存放拥有相关联对象锁的线程id

Mutex Lock 的切换需要从用户态转换到核心态中,因此状态转换需要耗费很多的处理器时间。

image-20220922013243561


Java 6之后

为了减少获得锁和释放锁所带来的性能消耗, 引入了轻量级锁和偏向锁 ,这是一个逐步升级锁的过程。

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

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到