本次讨论基于jdk1.8。按synchronized锁升级理论所说,加锁状态有四种,从轻到重分别为无锁->偏向锁->轻量级锁->独占锁(重量级锁)。但在实际模拟的时候发现synchronized直接从无锁状态变为了轻量级锁。接下来是实验过程,在此之前先了解下各种锁在对象头中的表现,重点关注对象头首字节后三位。对应关系表如下
锁状态 | 暂不关注 | 偏向锁标记位(1) | 锁状态标记(1) |
无锁 | 0 | 01 | |
轻量级锁 | 00 | ||
重量级锁 | 10 | ||
GC标记 | 11 | ||
偏向锁 | 1 | 01 |
在本次实验中,需引入如下jar包,maven引入方式如下
<dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.9</version> </dependency>
测试代码如下
public class JOLTest { public static void main(String[] args) throws IOException { JOLTest lock=new JOLTest(); System.out.println(ClassLayout.parseInstance(lock).toPrintable()); synchronized (lock){ System.out.println(ClassLayout.parseInstance(lock).toPrintable()); } } }
输出
锁状态由无锁变为轻量级锁,并没有经过偏向锁
查资料验证后发现有一参数控制偏向锁在jvm启动后多久开启,具体参数有两个
-XX:-UseBiasedLocking:控制偏向锁是否开启,jdk1.8中默认为true,jdk13中舍弃
-XX:BiasedLockingStartupDelay:偏向锁在JVM开启后多长时间开启,默认为4秒
所以,在上述程序启动是增加如下属性
运行后结果如下:
如上,成功观察到偏向锁