求助synchronized底层原理,锁升级过程到底是怎么样的?

synchronized底层原理,关于无锁、偏向锁、轻量级锁、重量级锁问题

public static void main(String[] args) throws InterruptedException {
        //HotSpot 虚拟机在启动后有个 4s 的延迟才会对每个新建的对象开启偏向锁模式
        Thread.sleep(5000);
        Object obj = new Object();
        System.out.println("匿名偏向状态 =====================" + "\n" + ClassLayout.parseInstance(obj).toPrintable());
        new Thread(() -> {
            synchronized (obj) {
                System.out.println(Thread.currentThread().getName() + "获取锁执行中。。。\n"
                        + ClassLayout.parseInstance(obj).toPrintable());
            }
        }, "thread-a").start();
        
        // 这段代码未注释时会出现两种结果:
        // 结果1:初始化偏向锁(未偏向)-->偏向锁(线程A)->偏向锁(线程B)
        // 结果2:初始化偏向锁(未偏向)-->偏向锁(线程A)->轻量级锁(线程B)->无锁
        // 代码注释也会有两种结果:
        // 结果1:初始化偏向锁(未偏向)-->偏向锁(线程A)->重量级锁(线程B)->无锁
        // 结果2:初始化偏向锁(未偏向)-->重量级锁(线程A)->重量级锁(线程B)->无锁
        Thread.sleep(1000);

        new Thread(() -> {
            synchronized (obj) {
                System.out.println(Thread.currentThread().getName() + "获取锁执行中。。。\n"
                        + ClassLayout.parseInstance(obj).toPrintable());
            }
        }, "thread-b").start();

        // 睡眠5s后
        Thread.sleep(5000);
        System.out.println(Thread.currentThread().getName() + ClassLayout.parseInstance(obj).toPrintable());
    }

image.png
image.png

    Thread.sleep(1000);
    // 这段代码未注释时会出现两种结果:
    // 结果1:初始化偏向锁(未偏向)-->偏向锁(线程A)->偏向锁(线程B)
    // 结果2:初始化偏向锁(未偏向)-->偏向锁(线程A)->轻量级锁(线程B)->无锁
    // 代码注释也会有两种结果:
    // 结果1:初始化偏向锁(未偏向)-->偏向锁(线程A)->重量级锁(线程B)->无锁
    // 结果2:初始化偏向锁(未偏向)-->重量级锁(线程A)->重量级锁(线程B)->无锁

**以上代码JDK版本1.8**
看了网上很多视频和文章的分析,总结下来是大多数讲的没那么深,而且有一些细节地方每篇文章可能分析的都不一样,参考那些技术的分析还是没有弄懂为什么会产生这几种不同的结果,底层的锁升级逻辑到底是怎样的呢,有没有大佬帮忙仔细分析下呢,如果能带着一起看源码那最好了......
    
阅读 883
1 个回答
                匿名偏向状态 =====================
                java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           58 0d 00 00 (01011000 00001101 00000000 00000000) (3416)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

                        thread-a获取锁执行中。。。
                        java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           d0 f3 7f 2b (11010000 11110011 01111111 00101011) (729805776)
      4     4        (object header)                           e3 00 00 00 (11100011 00000000 00000000 00000000) (227)
      8     4        (object header)                           58 0d 00 00 (01011000 00001101 00000000 00000000) (3416)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

                        thread-b获取锁执行中。。。
                        java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           40 f0 2f 2b (01000000 11110000 00101111 00101011) (724561984)
      4     4        (object header)                           e3 00 00 00 (11100011 00000000 00000000 00000000) (227)
      8     4        (object header)                           58 0d 00 00 (01011000 00001101 00000000 00000000) (3416)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

mainjava.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           58 0d 00 00 (01011000 00001101 00000000 00000000) (3416)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

我运行几次都是这个样子,高版本的jvm 已经废弃了偏向锁。所以结果比较符合预期,依次为 01,00,00,01 无锁,轻量级锁,轻量级锁,无锁。这样,就很符合预期了,要不就别纠结偏向锁了吧。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题