Java对象锁升级过程详解

Java对象的锁升级过程

在JDK1.7版本之后,对Sunchronized关键字进行了优化,如果对对象进行Synchronized进行加锁,那么针对资源的竞争情况不同,锁会有一个升级的过程,以保证资源是最佳的利用状况。

过程可以概括为:
无锁(new对象)-偏向锁-轻量级锁(无锁,自旋锁如CAS,自适应锁)-重量级锁

刚new对象,是无锁状态,加锁编程偏向锁,有人征用,升级为轻量锁,竞争频繁,升级为重量级锁。

上一篇我们介绍了对象的内存布局,结合它我们来进一步分析。
Java对象锁升级过程详解
刚new时,25位没用;identity hashcode,只有调用的时候才有值;分代年龄;锁状态;锁标志位01;

偏向锁:当线程调用到这个对象的时候,在mark word里面,用54位记录了指向当前线程的指针,说明这个锁当前属于该线程;epoch先不讲;1位没有用到;偏向锁位由0变成1;

轻量级锁:当有别的线程来竞争锁的时候,取消偏向锁;62位里面存的是指向某个线程lock record的指针,当有别的线程过来需要竞争锁的时候,(线程的线程栈里会有LR(lock record),去竞争锁,看谁能把指针指向该锁,CAS,线程去修改mark word的指向LR的指针,CAS),所以叫做自旋锁。

重量级锁:有些线程自旋超过10次,或者等着的线程超过CPU线程的一半,JDK1.6之后,JVM自适应自选,自己来控制上述参数。锁升级为重量级锁。 Mark word里62位指向的是重量级锁的指针(重量级锁需经过内核批准)。那么线程会进入一个该锁的队列,在队列里等待,是不消耗cpu的。

锁降级:特定情况下会发生,比如在GC的时候,因此没啥意义。

Java对象锁升级过程详解
Java对象锁升级过程详解