Synchronized锁的升级

本文详细解析了JDK1.6后的锁升级机制,包括无锁、偏向锁、轻量级锁和重量级锁的转换过程。探讨了锁升级如何提升多线程效率,以及锁消除和锁粗化的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

什么是锁升级

什么是锁消除

什么是锁粗化

什么是Mark Word

锁升级的过程


 

什么是锁升级

 

使用Synchronized会让其他线程阻塞,这样很影响程序的总体效率。因此jdk1.6以后优化了Synchronized机制即——锁升级

锁升级的过程为:无锁=》偏向锁=》轻量级锁=》重量级锁

注意:锁是不会降级的!

 

 

什么是锁消除

 

假如你在一个方法中用到了锁,但JVM并没有检查到有共享数据竞争的问题,为了减少性能损耗,JVM会把你的这个锁消除掉

 

 

什么是锁粗化

 

让锁的作用范围尽可能的小,这样可以让锁内代码尽可能少,缩短锁的持有时间。

但锁粗化并不都是有益的。比如有一个for循环,你频繁在for循环里面上锁,释放锁非常影响性能

 

什么是Mark Word

 

Mark Word用来存储对象运行时数据,用来记录对象运行时的一些参数,如:GC年龄,HashCode,锁标志,栈中的指针等

 

 

锁升级的过程

 

1.当没有对象上锁,对象为普通的对象。锁标志位为01,偏向锁标志为0

2.当对象被当作同步锁(Synchronized),假如线程A抢到了。锁标志依然为01,偏向锁标志变为1,此时锁升级为偏向锁。

偏向锁意味着如果再次进入或者退出同一段同步代码块,并不在需要进行加锁或解锁

3.当线程A再次试图获取锁时,JVM发现同步锁对象标志位是01,偏向锁标志为1。MarkWord会记录线程id就是A的id,表示A可以执行同步代码块。

4.当线程B尝试获取锁,JVM发现已经有人占用了,并且线程ID不是B的ID,因此B会先用CAS尝试比较并交换,成功则B获得锁,失败B会进入自旋。

5.B失败后说明锁存在竞争,这样就会导致”偏向锁升级为轻量级锁“。B会再次和A进行CAS比较并交换

6.如果轻量级锁后B仍然抢锁失败,就会使用自旋锁循环,自旋次数由JVM决定。如果某一时间成功,B获得锁。

7.如果B仍然抢锁失败,轻量级锁会升级为重量级锁,标志位改成10,在这个状态下未抢到锁的线程都会被阻塞,并由操作系统底层的Monitor来管理,这样就会出现CPU用户态和内核态的切换,会消耗资源——又名”重量级锁“

 

一个对象刚开始实例化的时候,没有任何线程来访问它。它是可偏向的,意味着它现在认为只可能有一个线程访问它,因此第一个线程访问它之后会偏向第一个线程,这个线程在执行偏向锁操作时使用了CAS,将对象头的ThreadID改成自己的ID,之后再次访问这个对象只需要比较ID,而不需要再使用CAS进行操作。

 

一旦有第二个线程访问这个对象,因为偏向锁不会主动释放,所以第二个线程可以看到对象是偏向锁状态。此时该对象已经存在锁竞争了,会检查原来持有该对象锁的线程是否依然存活,如果挂了则可改变成无锁状态,然后重新偏向新的线程,如果原来的线程依然存活,则马上执行那个线程的操作栈,如果仍然持有偏向锁,会被升级成轻量级锁,如果不存在使用了,将对象恢复到无锁的状态,然后重新偏向。

 

轻量级锁认为竞争存在,但是竞争的程度很轻,一般两个线程对于同一个锁的操作都会错开(自旋),当自旋超过一定次数,或一个线程持有锁,一个线程在自旋,这时来了第三个线程,轻量级锁会膨胀为重量级锁,重量级锁使除了拥有锁的线程外的其他线程全部阻塞,防止CPU空转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值