Synchronized底层原理进阶
Monitor实现的锁属于重量级锁,你了解过锁升级?
为什么叫做重量级锁
重量级锁
- Monitor实现的锁属于重量级锁,里面涉及到用户态(java代码)和内核态(CPU)的切换,进程的上下文切换,成本较高,性能比较低
- JDK6后引入了两种新的锁:偏向锁和轻量锁,它们的引入是为了解决在没有多线程竞争或基本没有竞争的场景下因为使用传统锁机制带来的性能开销问题
对象怎么关联上Monitor:
Java对象的内存结构
在HotSpot虚拟机中,对象在内存中存储的布局可分为3块区域:
- 对象头(Header)
- 实例数据(Instance Data)
- 对象填充
对象头:
- markWord 对象头
- klass word 描述对象实例的具体类型
markWord
32bit位:
- 001 没有占用锁
- 101 偏向锁
- 00 轻量级锁
- 10 重量级锁(在Markword中记录了Monitor的地址,就将Monitor关联起来了)
- 11 标记为GC
轻量级锁
在很多情况下,java程序运行时,同步块中的代码都是不存在竞争的,不同的线程交替的执行同步代码块中的代码。这种情况下,重量级锁是没有必要的,因此JVM引入了轻量级锁的概念。
同一个线程,两次获取的都是同样的Obj对象锁,这时候优先使用的就是轻量级锁。
轻量级锁流程
偏向锁
轻量级锁在没有竞争时(就自己这线程),每次重入仍然需要执行CAS操作。
JDK6中引入偏向锁来进一步优化,只有第一次使用CAS将线程ID设置到对象的Mark Word头,之后发现这个线程ID是自己的就表示没有竞争,不用重新CAS,以后只要不发生竞争,这个对象就归该线程所有。
Monitor实现的锁属于重量级锁,你了解过锁升级?
Java中Synchronized有偏向锁、轻量级锁、重量级锁形式,分别对应锁只能被一个线程持有、不同线程交替持有、多线程竞争三种情况。
一旦锁发生了竞争,都会升级为重量级锁