大家都知道synchronized优化后有多种锁(如偏向锁,轻量级锁),但是我如何知道我这段代码目前到底是什么锁呢?这就是本文介绍的JOL
首先得了解下对象内存布局,我们主要关注mark word,其他暂时不讲解
64位虚拟机的markword如下所示,等会我们的结果分析也需要对照这张图,图片来源于网络
接下来进入实战,我们需要引入jol依赖
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
写一个测试类
public class SynchronizedTest {
public static void main(String[] args) throws InterruptedException {
SynchronizedTest synchronizedTest = new SynchronizedTest();
synchronized (synchronizedTest) {
System.out.println(Thread.currentThread().getName()+" 1: " + ClassLayout.parseInstance(synchronizedTest).toPrintable());
}
}
看看输出结果
我是64位的jvm,但是为什么类型指针只有32位啊,因为默认是开启了指针压缩的,idea添加 vm options参数: -XX:-UseCompressedOops:关闭指针压缩,你会发现就有64位了,没有对齐填充了。
禁用指针压缩结果:
要看懂此结果我们还需要了解大端存储和小端存储,如果已经知道的略过此部分直接看最后。
大小端的最小单位是字节(1个字节8位),即大小端决定的是字节的排序。
大端存储:数据的高字节存储在低地址中,数据的低字节存储在高地址中
小端存储:数据的高字节存储在高地址中,数据的低字节存储在低地址中
以上就是概念,举个例子你就能懂了:
十进制数9877,它的二进制为10011010010101,如果用小端存储表示则为:
高地址 <- - - - - - - - 低地址
10010101[高序字节] 00100110[低序字节]
用大端存储表示则为:
高地址 <- - - - - - - - 低地址
00100110[低序字节] 10010101[高序字节]
接下来再看到结果图:
java默认的是小端存储,所以他的读取结果就是 以下64位:
00000000 00000000 01111111 11010101 10111110 10000000 11000000
00000101最后三位是101,就是偏向锁(这里看不懂,再回去看看mark word的组成)
小提示:偏向锁默认4s延迟后才会启动哦
公众号回复 jol代码 获取我的完整测试代码