java并发编程(八)synchronized原理之偏向锁

作者: 我犟不过你 | 来源:发表于2021-11-29 17:15 被阅读0次

    偏向锁的引入,对轻量级锁的CAS操作进行了优化。轻量级锁需要每次都是用CAS来尝试获取锁,占用CPU时间。

    jdk1.6中引入偏向锁后,只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word 头,之后发现这个线程 ID 是自己的就表示没有竞争,不用重新 CAS。以后只要不发生竞争,这个对象就归该线程所有。

    一、偏向锁的状态

    |----------------------------------------------------------------------------------------------|
    |                                   Mark Word(64bits)                     |      State         |
    |----------------------------------------------------------------------------------------------|
    |    unused:25|identity_hashcode:31|unused:1|age:4|biase_lock:0| lock:01  |      Nomal         |
    |----------------------------------------------------------------------------------------------|
    |    thread:54|      epoch:2       |unused:1|age:4|biase_lock:1| lock:01  |      Biased        |
    |----------------------------------------------------------------------------------------------|
    |                        ptr_to_lock_record:62                 | lock:00  | Lightweight Locked |
    |----------------------------------------------------------------------------------------------|
    |                       ptr_to_heavyweight_monitor:62          | lock:10  | Heavyweight Locked |
    |----------------------------------------------------------------------------------------------|
    |                                                              | lock:11  |    Marked for GC   |
    |----------------------------------------------------------------------------------------------|
    

    如上表所示,偏向锁的状态biase_lock是1,lock是01。

    下面我们借用jol工具看下状态:

    <!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
    <dependency>
        <groupId>org.openjdk.jol</groupId>
        <artifactId>jol-core</artifactId>
        <version>0.16</version>
    </dependency>
    

    1.1 默认情况下的偏向锁

    引入依赖后,有如下代码:

        public static void main(String[] args)  {
    
            Object lock = new Object();
    
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    

    结果:

    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
      8   8        (object header: class)    0x000000001be01c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    

    我们只关注上述结果的mark word 部分,后面的括号当中的内容是non-biasable,就是没开启偏向锁。并且value的值是001结尾,对照上面的Mark Word 状态表的后三位,刚好是无锁状态,0,01。

    此处有一个问题,偏向锁是延时的,在刚启动的时候并没有开启,我们可以使用以下参数设置立即生效:

     -XX:BiasedLockingStartupDelay=0
    

    设置完参数后再次启动的结果如下,发现16进制的value是5,转为2进制就是101,是上表中偏向锁状态的后三位,并且括号内的内容变成了biasable,具有了偏向锁的能力:

    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000000000005 (biasable; age: 0)
      8   8        (object header: class)    0x000000001c0a1c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    • 总结:
      • 偏向锁是默认开启的,但是是延时的,需要通过参数-XX:BiasedLockingStartupDelay=0禁用延时。
      • 对象在创建后,如果开启了偏向锁,thread、epoch、age 都为 0。
      • 对象在创建后,如果没有开启偏向锁,hashcode、age 都为 0。
      • 禁用偏向锁,使用-XX:-UseBiasedLocking参数。

    1.2 线程持有偏向锁

    1.2.1 单线程持有

    当有线程持有上述偏向锁,那么对象头的Mark Word 会有什么变化呢? 代码如下:

        public static void main(String[] args) {
    
            Object lock = new Object();
    
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    
            synchronized (lock) {
                System.out.println(ClassLayout.parseInstance(lock).toPrintable());
            }
    
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    

    在锁被持有前,持有中,持有后的状态分别如下:

    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000000000005 (biasable; age: 0)
      8   8        (object header: class)    0x000000001c081c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x000000000320a005 (biased: 0x000000000000c828; epoch: 0; age: 0)
      8   8        (object header: class)    0x000000001c081c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x000000000320a005 (biased: 0x000000000000c828; epoch: 0; age: 0)
      8   8        (object header: class)    0x000000001c081c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    

    如上所示,当锁被线程持有后,mark word的内容发生了变化。其中value是8字节的全部内容,末尾是005,转化成2进制就是101,确实是使用的偏向锁。在括号内的biased表示偏向锁在哪个线程上,后面的16进制数,就是线程的id。

    在锁被释放后,当前对象仍然是持有该偏向锁的。

    1.2.2 两个线程竞争

    有如下代码,使用main方法的主线程和一个Thread模仿一个锁竞争的情况,看看对象头是如何变化的。

        public static void main(String[] args) throws InterruptedException {
    
            Object lock = new Object();
            // 打印初始状态
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    
            synchronized (lock) {
                // 打印偏向锁状态
                System.out.println(ClassLayout.parseInstance(lock).toPrintable());
                TimeUnit.SECONDS.sleep(2);
            }
    
            TimeUnit.SECONDS.sleep(1);
            new Thread(()->{
                synchronized (lock){
                    // 打印轻量级锁
                    System.out.println(ClassLayout.parseInstance(lock).toPrintable());
                }
            }).start();
    
            TimeUnit.SECONDS.sleep(1);
            // 打印无锁
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    

    结果如下所示:

    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000000000005 (biasable; age: 0)
      8   8        (object header: class)    0x000000001bbd1c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000002e1a005 (biased: 0x000000000000b868; epoch: 0; age: 0)
      8   8        (object header: class)    0x000000001bbd1c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000020b5efe0 (thin lock: 0x0000000020b5efe0)
      8   8        (object header: class)    0x000000001bbd1c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
      8   8        (object header: class)    0x000000001bbd1c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    

    过程分析:

    • 新创建对象,开启偏向锁
    • 当主线程获取锁后,独自持有偏向锁,阻塞2s
    • 一秒后,另一个线程来竞争此锁,此时因为主线程在阻塞,所以此线程升级成了轻量级锁,如上结果thin lock表示轻量级锁,后面的16进制数表示持有锁的线程id。
    • 当主线程再次休息一秒,同步代码块执行完毕,此时释放锁,所以最终变成了无锁状态non-biasable

    1.2.3 多个线程竞争

    使用5个线程竞争:

        public static void main(String[] args) throws InterruptedException {
    
            Object lock = new Object();
            // 打印初始状态
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    
            synchronized (lock) {
                // 打印偏向锁状态
                System.out.println(ClassLayout.parseInstance(lock).toPrintable());
                TimeUnit.SECONDS.sleep(2);
            }
    
            TimeUnit.SECONDS.sleep(1);
    
            new Thread(() -> {
                synchronized (lock) {
                    // 打印轻量级锁
                    System.out.println(ClassLayout.parseInstance(lock).toPrintable());
                }
            }).start();
    
            TimeUnit.SECONDS.sleep(1);
    
            // 5个线程竞争
            for (int i = 0; i < 5; i++) {
                new Thread(() -> {
                    synchronized (lock) {
                        // 打印轻量级锁
                        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
                    }
                }).start();
            }
    
            TimeUnit.SECONDS.sleep(1);
            // 打印无锁
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    

    结果如下所示:

    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000000000005 (biasable; age: 0)
      8   8        (object header: class)    0x000000001b941c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000002ada005 (biased: 0x000000000000ab68; epoch: 0; age: 0)
      8   8        (object header: class)    0x000000001b941c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x00000000208df7f0 (thin lock: 0x00000000208df7f0)
      8   8        (object header: class)    0x000000001b941c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x000000001c33a60a (fat lock: 0x000000001c33a60a)
      8   8        (object header: class)    0x000000001b941c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x000000001c33a60a (fat lock: 0x000000001c33a60a)
      8   8        (object header: class)    0x000000001b941c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x000000001c33a60a (fat lock: 0x000000001c33a60a)
      8   8        (object header: class)    0x000000001b941c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x000000001c33a60a (fat lock: 0x000000001c33a60a)
      8   8        (object header: class)    0x000000001b941c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x000000001c33a60a (fat lock: 0x000000001c33a60a)
      8   8        (object header: class)    0x000000001b941c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
      8   8        (object header: class)    0x000000001b941c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    

    前面的过程,与上一小节的测试结果没有不同,不同处在于后面的循环创建的5个线程,此时打印的对象头内容是fat lock,表示重量级锁,其后面跟着的16进制数表示Monitor的地址,多个线程竞争时,未获取到锁的线程将会添加到Monitor的EntryList当中,等待唤醒。

    二、锁撤销

    2.1 hashcode

    在创建对象的时候,hashcode是0,只有当调用该对象后,hashcode才被赋值,如下代码所示:

        public static void main(String[] args) throws InterruptedException {
    
            Object lock = new Object();
            // 打印初始状态
            System.out.println(lock);
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    

    结果如下:

    java.lang.Object@16f65612
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x00000016f6561201 (hash: 0x16f65612; age: 0)
      8   8        (object header: class)    0x000000001c051c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    • 轻量级锁会在锁记录中记录 hashCode
    • 重量级锁会在 Monitor 中记录 hashCode

    调用对象的hashcode()方法,会使对象的偏向锁被撤销:

        public static void main(String[] args) throws InterruptedException {
    
            Object lock = new Object();
            // 打印初始状态
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    
    
            synchronized (lock) {
                // 打印偏向锁状态
                System.out.println(ClassLayout.parseInstance(lock).toPrintable());
            }
    
            //调用hashcode
            lock.hashCode();
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    
            //再次获取锁
            synchronized (lock) {
                // 打印偏向锁状态
                System.out.println(ClassLayout.parseInstance(lock).toPrintable());
            }
        }
    

    结果:

    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000000000005 (biasable; age: 0)
      8   8        (object header: class)    0x000000001be21c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x000000000305a005 (biased: 0x000000000000c168; epoch: 0; age: 0)
      8   8        (object header: class)    0x000000001be21c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000002ed94a8b01 (hash: 0x2ed94a8b; age: 0)
      8   8        (object header: class)    0x000000001be21c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    
    java.lang.Object object internals:
    OFF  SZ   TYPE DESCRIPTION               VALUE
      0   8        (object header: mark)     0x0000000002faf730 (thin lock: 0x0000000002faf730)
      8   8        (object header: class)    0x000000001be21c00
    Instance size: 16 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    

    如上所示:发现调用hashcode后,对象头打印出了hash值,并且将value的值转换成二进制后得到后三位的结果是001,001表示无锁的正常状态。

    当再次尝试获取锁的时候,发现获取到的只能是轻量级锁(thin lock)了。

    2.2 偏向锁锁撤销 - 升级轻量级锁或重量级锁

    这里就是前面偏向锁状态当中,当有多个线程竞争锁的时候,无论是升级成轻量级锁,还是重量级锁,在最终将锁释放后,都会变成无锁状态, 即偏向锁的状态被撤销了。

    2.3 重偏向优化

    如果对象虽然被多个线程访问,但没有竞争,这时偏向了线程 T1 的对象仍有机会重新偏向 T2,重偏向会重置对象的 Thread ID。

    当撤销偏向锁阈值超过 14 次后(这个次数在我的电脑时14,有些人似乎20,暂时不知道怎么设定的),jvm 会这样觉得,我是不是偏向错了呢,于是会在给这些对象加锁时重新偏向至加锁线程。

    如下所示,有两个线程,t1组装一个大小为30的集合,结合内创建30个对象。t2在t1处理数据时,通过wait等待,当t1通过notify唤醒t2时,t2开始占有锁(30个对象,每一个都有自己的锁):

        public static void main(String[] args) {
            test3();
        }
    
        public static String print(String s) {
            String[] split = s.split("\r\n");
            return split[2].substring(41);
        }
    
        private static void test3() {
            Vector<Object> list = new Vector<>();
            Thread t1 = new Thread(() -> {
                for (int i = 0; i < 30; i++) {
                    Object d = new Object();
                    list.add(d);
                    synchronized (d) {
                        System.out.println(i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                    }
                }
                synchronized (list) {
                    list.notify();
                }
            }, "t1");
            t1.start();
    
            Thread t2 = new Thread(() -> {
                synchronized (list) {
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("===============> ");
                for (int i = 0; i < 30; i++) {
                    Object d = list.get(i);
                    System.out.println(i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                    synchronized (d) {
                        System.out.println(i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                    }
                    System.out.println(i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                }
            }, "t2");
            t2.start();
        }
    

    结果:

    0   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    1   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    2   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    3   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    4   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    5   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    6   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    7   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    8   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    9   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    10  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    11  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    12  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    13  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    14  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    15  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    16  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    17  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    18  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    19  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    20  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    21  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    22  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    23  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    24  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    25  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    26  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    27  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    28  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    29  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    ===============> 
    0   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    0   0x00000000210df370 (thin lock: 0x00000000210df370)
    0   0x0000000000000001 (non-biasable; age: 0)
    1   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    1   0x00000000210df370 (thin lock: 0x00000000210df370)
    1   0x0000000000000001 (non-biasable; age: 0)
    2   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    2   0x00000000210df370 (thin lock: 0x00000000210df370)
    2   0x0000000000000001 (non-biasable; age: 0)
    3   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    3   0x00000000210df370 (thin lock: 0x00000000210df370)
    3   0x0000000000000001 (non-biasable; age: 0)
    4   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    4   0x00000000210df370 (thin lock: 0x00000000210df370)
    4   0x0000000000000001 (non-biasable; age: 0)
    5   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    5   0x00000000210df370 (thin lock: 0x00000000210df370)
    5   0x0000000000000001 (non-biasable; age: 0)
    6   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    6   0x00000000210df370 (thin lock: 0x00000000210df370)
    6   0x0000000000000001 (non-biasable; age: 0)
    7   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    7   0x00000000210df370 (thin lock: 0x00000000210df370)
    7   0x0000000000000001 (non-biasable; age: 0)
    8   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    8   0x00000000210df370 (thin lock: 0x00000000210df370)
    8   0x0000000000000001 (non-biasable; age: 0)
    9   0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    9   0x00000000210df370 (thin lock: 0x00000000210df370)
    9   0x0000000000000001 (non-biasable; age: 0)
    10  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    10  0x00000000210df370 (thin lock: 0x00000000210df370)
    10  0x0000000000000001 (non-biasable; age: 0)
    11  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    11  0x00000000210df370 (thin lock: 0x00000000210df370)
    11  0x0000000000000001 (non-biasable; age: 0)
    12  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    12  0x00000000210df370 (thin lock: 0x00000000210df370)
    12  0x0000000000000001 (non-biasable; age: 0)
    13  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    13  0x00000000210df370 (thin lock: 0x00000000210df370)
    13  0x0000000000000001 (non-biasable; age: 0)
    14  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    14  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    14  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    15  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    15  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    15  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    16  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    16  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    16  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    17  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    17  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    17  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    18  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    18  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    18  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    19  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    19  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    19  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    20  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    20  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    20  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    21  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    21  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    21  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    22  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    22  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    22  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    23  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    23  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    23  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    24  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    24  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    24  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    25  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    25  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    25  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    26  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    26  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    26  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    27  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    27  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    27  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    28  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    28  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    28  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    29  0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
    29  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    29  0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
    
    • ===============>之前的30个对象,都是偏向于0x000000000008019e这个线程(t1)。
    • ===============>之后开始进行了锁升级,升级成了轻量级锁(thin lock),释放后变成无锁状态(non-biasable)。
    • 在经历14次锁升级,锁撤销后,发现第15次不在进行此类操作,而是直接修改偏向线程的id了。

    因为锁升级和锁撤销会带来一定的性能损耗,所以jvm在这方面做了重偏向的优化。

    2.4 批量锁撤销

    当撤销偏向锁阈值超过 14 次后,jvm 会这样觉得,自己确实偏向错了,根本就不该偏向。于是整个类的所有对象都会变为不可偏向的,新建的对象也是不可偏向的。

    使用三个线程,初始化一个50个对象的集合,t1处理数据,唤醒t2;t2处理完数据唤醒t3;代码如下:

        static Thread t1, t2, t3;
    
        public static void main(String[] args) throws InterruptedException {
            test3();
        }
    
        public static String print(String s) {
            String[] split = s.split("\r\n");
            return split[2].substring(41);
        }
    
        private static void test3() throws InterruptedException {
            Vector<Object> list = new Vector<>();
            t1 = new Thread(() -> {
                for (int i = 0; i < 50; i++) {
                    Object d = new Object();
                    list.add(d);
                    synchronized (d) {
                        System.out.println(i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                    }
                }
                LockSupport.unpark(t2);
            }, "t1");
            t1.start();
    
            t2 = new Thread(() -> {
                LockSupport.park();
                System.out.println("=========第二阶段======> ");
                for (int i = 0; i < 50; i++) {
                    Object d = list.get(i);
                    System.out.println("t2: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                    synchronized (d) {
                        System.out.println("t2: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                    }
                    System.out.println("t2: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                }
                LockSupport.unpark(t3);
            }, "t2");
            t2.start();
    
    
            t3 = new Thread(() -> {
                LockSupport.park();
                System.out.println("=========第三阶段======>");
                for (int i = 0; i < 50; i++) {
                    Object d = list.get(i);
                    System.out.println("t3: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                    synchronized (d) {
                        System.out.println("t3: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                    }
                    System.out.println("t3: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
                }
            }, "t3");
            t3.start();
    
            t3.join();
            // 输出一个新的对象的对象头,发现是不可偏向锁
            System.out.println(print(ClassLayout.parseInstance(new Object()).toPrintable()));
        }
    

    结果:

    0   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    1   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    2   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    3   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    4   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    5   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    6   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    7   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    8   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    9   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    10  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    11  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    12  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    13  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    14  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    15  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    16  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    17  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    18  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    19  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    20  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    21  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    22  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    23  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    24  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    25  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    26  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    27  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    28  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    29  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    30  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    31  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    32  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    33  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    34  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    35  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    36  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    37  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    38  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    39  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    40  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    41  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    42  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    43  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    44  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    45  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    46  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    47  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    48  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    49  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    =========第二阶段======> 
    t2: 0   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 0   0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 0   0x0000000000000001 (non-biasable; age: 0)
    t2: 1   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 1   0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 1   0x0000000000000001 (non-biasable; age: 0)
    t2: 2   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 2   0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 2   0x0000000000000001 (non-biasable; age: 0)
    t2: 3   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 3   0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 3   0x0000000000000001 (non-biasable; age: 0)
    t2: 4   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 4   0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 4   0x0000000000000001 (non-biasable; age: 0)
    t2: 5   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 5   0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 5   0x0000000000000001 (non-biasable; age: 0)
    t2: 6   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 6   0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 6   0x0000000000000001 (non-biasable; age: 0)
    t2: 7   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 7   0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 7   0x0000000000000001 (non-biasable; age: 0)
    t2: 8   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 8   0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 8   0x0000000000000001 (non-biasable; age: 0)
    t2: 9   0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 9   0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 9   0x0000000000000001 (non-biasable; age: 0)
    t2: 10  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 10  0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 10  0x0000000000000001 (non-biasable; age: 0)
    t2: 11  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 11  0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 11  0x0000000000000001 (non-biasable; age: 0)
    t2: 12  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 12  0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 12  0x0000000000000001 (non-biasable; age: 0)
    t2: 13  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 13  0x000000002130f160 (thin lock: 0x000000002130f160)
    t2: 13  0x0000000000000001 (non-biasable; age: 0)
    t2: 14  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 14  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 14  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 15  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 15  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 15  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 16  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 16  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 16  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 17  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 17  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 17  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 18  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 18  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 18  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 19  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 19  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 19  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 20  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 20  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 20  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 21  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 21  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 21  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 22  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 22  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 22  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 23  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 23  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 23  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 24  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 24  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 24  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 25  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 25  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 25  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 26  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 26  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 26  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 27  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 27  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 27  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 28  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 28  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 28  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 29  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 29  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 29  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 30  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 30  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 30  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 31  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 31  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 31  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 32  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 32  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 32  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 33  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 33  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 33  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 34  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 34  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 34  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 35  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 35  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 35  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 36  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 36  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 36  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 37  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 37  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 37  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 38  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 38  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 38  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 39  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 39  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 39  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 40  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 40  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 40  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 41  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 41  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 41  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 42  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 42  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 42  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 43  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 43  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 43  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 44  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 44  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 44  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 45  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 45  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 45  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 46  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 46  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 46  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 47  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 47  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 47  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 48  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 48  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 48  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 49  0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
    t2: 49  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t2: 49  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    =========第三阶段======>
    t3: 0   0x0000000000000001 (non-biasable; age: 0)
    t3: 0   0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 0   0x0000000000000001 (non-biasable; age: 0)
    t3: 1   0x0000000000000001 (non-biasable; age: 0)
    t3: 1   0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 1   0x0000000000000001 (non-biasable; age: 0)
    t3: 2   0x0000000000000001 (non-biasable; age: 0)
    t3: 2   0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 2   0x0000000000000001 (non-biasable; age: 0)
    t3: 3   0x0000000000000001 (non-biasable; age: 0)
    t3: 3   0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 3   0x0000000000000001 (non-biasable; age: 0)
    t3: 4   0x0000000000000001 (non-biasable; age: 0)
    t3: 4   0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 4   0x0000000000000001 (non-biasable; age: 0)
    t3: 5   0x0000000000000001 (non-biasable; age: 0)
    t3: 5   0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 5   0x0000000000000001 (non-biasable; age: 0)
    t3: 6   0x0000000000000001 (non-biasable; age: 0)
    t3: 6   0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 6   0x0000000000000001 (non-biasable; age: 0)
    t3: 7   0x0000000000000001 (non-biasable; age: 0)
    t3: 7   0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 7   0x0000000000000001 (non-biasable; age: 0)
    t3: 8   0x0000000000000001 (non-biasable; age: 0)
    t3: 8   0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 8   0x0000000000000001 (non-biasable; age: 0)
    t3: 9   0x0000000000000001 (non-biasable; age: 0)
    t3: 9   0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 9   0x0000000000000001 (non-biasable; age: 0)
    t3: 10  0x0000000000000001 (non-biasable; age: 0)
    t3: 10  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 10  0x0000000000000001 (non-biasable; age: 0)
    t3: 11  0x0000000000000001 (non-biasable; age: 0)
    t3: 11  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 11  0x0000000000000001 (non-biasable; age: 0)
    t3: 12  0x0000000000000001 (non-biasable; age: 0)
    t3: 12  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 12  0x0000000000000001 (non-biasable; age: 0)
    t3: 13  0x0000000000000001 (non-biasable; age: 0)
    t3: 13  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 13  0x0000000000000001 (non-biasable; age: 0)
    t3: 14  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 14  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 14  0x0000000000000001 (non-biasable; age: 0)
    t3: 15  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 15  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 15  0x0000000000000001 (non-biasable; age: 0)
    t3: 16  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 16  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 16  0x0000000000000001 (non-biasable; age: 0)
    t3: 17  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 17  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 17  0x0000000000000001 (non-biasable; age: 0)
    t3: 18  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 18  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 18  0x0000000000000001 (non-biasable; age: 0)
    t3: 19  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 19  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 19  0x0000000000000001 (non-biasable; age: 0)
    t3: 20  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 20  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 20  0x0000000000000001 (non-biasable; age: 0)
    t3: 21  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 21  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 21  0x0000000000000001 (non-biasable; age: 0)
    t3: 22  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 22  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 22  0x0000000000000001 (non-biasable; age: 0)
    t3: 23  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 23  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 23  0x0000000000000001 (non-biasable; age: 0)
    t3: 24  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 24  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 24  0x0000000000000001 (non-biasable; age: 0)
    t3: 25  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 25  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 25  0x0000000000000001 (non-biasable; age: 0)
    t3: 26  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 26  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 26  0x0000000000000001 (non-biasable; age: 0)
    t3: 27  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 27  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 27  0x0000000000000001 (non-biasable; age: 0)
    t3: 28  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 28  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 28  0x0000000000000001 (non-biasable; age: 0)
    t3: 29  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 29  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 29  0x0000000000000001 (non-biasable; age: 0)
    t3: 30  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 30  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 30  0x0000000000000001 (non-biasable; age: 0)
    t3: 31  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 31  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 31  0x0000000000000001 (non-biasable; age: 0)
    t3: 32  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 32  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 32  0x0000000000000001 (non-biasable; age: 0)
    t3: 33  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 33  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 33  0x0000000000000001 (non-biasable; age: 0)
    t3: 34  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 34  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 34  0x0000000000000001 (non-biasable; age: 0)
    t3: 35  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 35  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 35  0x0000000000000001 (non-biasable; age: 0)
    t3: 36  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 36  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 36  0x0000000000000001 (non-biasable; age: 0)
    t3: 37  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 37  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 37  0x0000000000000001 (non-biasable; age: 0)
    t3: 38  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 38  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 38  0x0000000000000001 (non-biasable; age: 0)
    t3: 39  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 39  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 39  0x0000000000000001 (non-biasable; age: 0)
    t3: 40  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 40  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 40  0x0000000000000001 (non-biasable; age: 0)
    t3: 41  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 41  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 41  0x0000000000000001 (non-biasable; age: 0)
    t3: 42  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 42  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 42  0x0000000000000001 (non-biasable; age: 0)
    t3: 43  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 43  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 43  0x0000000000000001 (non-biasable; age: 0)
    t3: 44  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 44  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 44  0x0000000000000001 (non-biasable; age: 0)
    t3: 45  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 45  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 45  0x0000000000000001 (non-biasable; age: 0)
    t3: 46  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 46  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 46  0x0000000000000001 (non-biasable; age: 0)
    t3: 47  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 47  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 47  0x0000000000000001 (non-biasable; age: 0)
    t3: 48  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 48  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 48  0x0000000000000001 (non-biasable; age: 0)
    t3: 49  0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
    t3: 49  0x000000002140f690 (thin lock: 0x000000002140f690)
    t3: 49  0x0000000000000001 (non-biasable; age: 0)
    0x0000000000000001 (non-biasable; age: 0)
    
    • 第二阶段其实就是前一章节讲的重偏向优化
    • 第三阶段开始,线程t3加入进来,前14个对象在第二阶段已经被撤销了偏向锁,所以这14个对象要不停的经历轻量级锁到锁撤销的状态。
    • 当第三阶段达到第15次时,这之后的对象都是偏向于线程t2的,需要经历锁撤销,轻量级锁的过程,到结束并没有进行一个所偏向的优化了。
    • 注意最后一行,当再次打印一个新创建的对象头时,发现是不可使用偏向锁的(关于这个阈值,有人说是40,我没有测试过)。

    相关文章

      网友评论

        本文标题:java并发编程(八)synchronized原理之偏向锁

        本文链接:https://www.haomeiwen.com/subject/eogkxrtx.html