大家都知道synchronized优化后有多种锁(如偏向锁,轻量级锁),但是我如何知道我这段代码目前到底是什么锁呢?这就是本文介绍的JOL
    首先得了解下对象内存布局,我们主要关注mark word,其他暂时不讲解

    JOL工具监控当前是偏向锁还是轻量级锁 - 图1

    64位虚拟机的markword如下所示,等会我们的结果分析也需要对照这张图,图片来源于网络
    JOL工具监控当前是偏向锁还是轻量级锁 - 图2

    接下来进入实战,我们需要引入jol依赖

    1. <dependency>
    2. <groupId>org.openjdk.jol</groupId>
    3. <artifactId>jol-core</artifactId>
    4. <version>0.9</version>
    5. </dependency>

    写一个测试类

    1. public class SynchronizedTest {
    2. public static void main(String[] args) throws InterruptedException {
    3. SynchronizedTest synchronizedTest = new SynchronizedTest();
    4. synchronized (synchronizedTest) {
    5. System.out.println(Thread.currentThread().getName()+" 1: " + ClassLayout.parseInstance(synchronizedTest).toPrintable());
    6. }
    7. }

    看看输出结果
    JOL工具监控当前是偏向锁还是轻量级锁 - 图3
    我是64位的jvm,但是为什么类型指针只有32位啊,因为默认是开启了指针压缩的,idea添加 vm options参数: -XX:-UseCompressedOops:关闭指针压缩,你会发现就有64位了,没有对齐填充了。
    禁用指针压缩结果:
    JOL工具监控当前是偏向锁还是轻量级锁 - 图4
    要看懂此结果我们还需要了解大端存储和小端存储,如果已经知道的略过此部分直接看最后。
    大小端的最小单位是字节(1个字节8位),即大小端决定的是字节的排序。
    大端存储:数据的高字节存储在低地址中,数据的低字节存储在高地址中
    小端存储:数据的高字节存储在高地址中,数据的低字节存储在低地址中
    以上就是概念,举个例子你就能懂了:
    十进制数9877,它的二进制为10011010010101,如果用小端存储表示则为:
    高地址 <- - - - - - - - 低地址
    10010101[高序字节] 00100110[低序字节]
    用大端存储表示则为:
    高地址 <- - - - - - - - 低地址
    00100110[低序字节] 10010101[高序字节]
    接下来再看到结果图:
    JOL工具监控当前是偏向锁还是轻量级锁 - 图5
    java默认的是小端存储,所以他的读取结果就是 以下64位:
    00000000 00000000 01111111 11010101 10111110 10000000 11000000 00000101
    最后三位是101,就是偏向锁(这里看不懂,再回去看看mark word的组成)
    小提示:偏向锁默认4s延迟后才会启动哦