11 偏向锁的重入 以及 线程1获取偏向锁并释放线程2获取锁 的调试

前言 

 

09 给对象添加偏向锁的调试

10 偏向锁的退出的调试

呵呵 接着前两篇 

本文调试一下 一下的几个场景

1. 偏向锁的重入

2. 线程1添加了偏向锁并释放, 线程2来获取锁  

 

 

一下内容基于 jdk9 + lldb-1001.0.13.3 

另外一下 运行时数据可能是来自于多次调试, 可能会存在运行时数据 对不上的情况, 但是的条理逻辑会在文字中描述清楚的 

 

 

偏向锁重入的测试用例

package com.hx.test04;

/**
 * Test26SynchronizeReentrantObject
 *
 * @author Jerry.X.He <[email protected]>
 * @version 1.0
 * @date 2020-04-03 15:14
 */
public class Test26SynchronizeReentrantObject implements Cloneable {

  // identStr
  private String identStr = "xyz";
  int f01;
  int f02;
  int f03;
  int f04;
  int f05;

  // Test26SynchronizeReentrantObject
  public static void main(String[] args) throws Exception {

    Test26SynchronizeReentrantObject lockObj = new Test26SynchronizeReentrantObject();

    synchronized (lockObj) {
      synchronized (lockObj) {

//        Test26SynchronizeReentrantObject cloned = (Test26SynchronizeReentrantObject) lockObj.clone();
//        System.out.println(lockObj.identStr);

      }
    }

  }

}

 

对应的字节码信息如下, 下面参照可能需要使用到 

master:classes jerry$ javap -c com/hx/test04/Test26SynchronizeReentrantObject.class 
Compiled from "Test26SynchronizeReentrantObject.java"
public class com.hx.test04.Test26SynchronizeReentrantObject implements java.lang.Cloneable {
  int f01;

  int f02;

  int f03;

  int f04;

  int f05;

  public com.hx.test04.Test26SynchronizeReentrantObject();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: aload_0
       5: ldc           #2                  // String xyz
       7: putfield      #3                  // Field identStr:Ljava/lang/String;
      10: return

  public static void main(java.lang.String[]) throws java.lang.Exception;
    Code:
       0: new           #4                  // class com/hx/test04/Test26SynchronizeReentrantObject
       3: dup
       4: invokespecial #5                  // Method "":()V
       7: astore_1
       8: aload_1
       9: dup
      10: astore_2
      11: monitorenter
      12: aload_1
      13: dup
      14: astore_3
      15: monitorenter
      16: aload_3
      17: monitorexit
      18: goto          28
      21: astore        4
      23: aload_3
      24: monitorexit
      25: aload         4
      27: athrow
      28: aload_2
      29: monitorexit
      30: goto          40
      33: astore        5
      35: aload_2
      36: monitorexit
      37: aload         5
      39: athrow
      40: return
    Exception table:
       from    to  target type
          16    18    21   any
          21    25    21   any
          12    30    33   any
          33    37    33   any
}

 

 

进入lldb的调试

同样的配方同样的味道, 这里就不在输出 一些 定位一下当前方法 的日志了, 直接进入 正题 

(lldb) p _active_table._table[9][194]
(address) $0 = 0x000000010524f980 "XH;"
(lldb) b 0x000000010524f980
Breakpoint 3: address = 0x000000010524f980
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 3.1
    frame #0: 0x000000010524f980
->  0x10524f980: popq   %rax
    0x10524f981: cmpq   (%rax), %rax
    0x10524f984: xorl   %esi, %esi
    0x10524f986: movq   -0x48(%rbp), %rcx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000747bb8798
       rbx = 0x00000000000000c2
       rcx = 0x0000000000000008
       rdx = 0x0000000747bb87b8
       rdi = 0x0000000101806000
       rsi = 0x000070000ba375c0
       rbp = 0x000070000ba37670
       rsp = 0x000070000ba37620
        r8 = 0x0000000000000000
        r9 = 0x0000000000000020
       r10 = 0x0000000104b0b270  libjvm.dylib`TemplateInterpreter::_active_table + 18432
       r11 = 0x00006fff0a229200
       r12 = 0x0000000000000000
       r13 = 0x000000011d1eff93
       r14 = 0x000070000ba376a8
       r15 = 0x0000000101806000
       rip = 0x000000010524f980
    rflags = 0x0000000000000206
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) p ((oopDesc*)0x0000000747bb8798)->print()
com.hx.test04.Test26SynchronizeReentrantObject
{0x0000000747bb8798} - klass: 'com/hx/test04/Test26SynchronizeReentrantObject'
 - ---- fields (total size 5 words):
 - 'f01' 'I' @12  0
 - 'f02' 'I' @16  0
 - 'f03' 'I' @20  0
 - 'f04' 'I' @24  0
 - 'f05' 'I' @28  0
 - private 'identStr' 'Ljava/lang/String;' @32  "xyz"{0x0000000747bb87c0} (e8f770f8 0)
(lldb) x 0x0000000747bb8798
0x747bb8798: 05 00 00 00 00 00 00 00 86 1f 01 f8 00 00 00 00  ...........?....
0x747bb87a8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
(lldb) x 0x000070000ba37620 -c 0x100
0x70000ba37620: 98 87 bb 47 07 00 00 00 28 76 a3 0b 00 70 00 00  ..?G....(v?..p..
0x70000ba37630: 8c ff 1e 1d 01 00 00 00 a8 76 a3 0b 00 70 00 00  .?......?v?..p..
0x70000ba37640: 88 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba37650: 70 82 bb 47 07 00 00 00 00 00 1f 1d 01 00 00 00  p.?G............
0x70000ba37660: 00 00 00 00 00 00 00 00 a8 76 a3 0b 00 70 00 00  ........?v?..p..
0x70000ba37670: 10 77 a3 0b 00 70 00 00 f1 09 20 05 01 00 00 00  .w?..p..?. .....
0x70000ba37680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba37690: 00 00 00 00 00 00 00 00 98 87 bb 47 07 00 00 00  ..........?G....
0x70000ba376a0: 98 87 bb 47 07 00 00 00 88 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba376b0: a0 1f 00 00 03 00 00 00 00 00 00 00 00 00 00 00  ?...............
0x70000ba376c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba376d0: 00 00 00 00 00 00 00 00 00 80 a3 0b 00 70 00 00  ..........?..p..
0x70000ba376e0: 20 78 a3 0b 00 70 00 00 50 7d a3 0b 00 70 00 00   x?..p..P}?..p..
0x70000ba376f0: 0a 00 00 00 00 70 00 00 00 00 1f 1d 01 00 00 00  .....p..........
0x70000ba37700: 00 a7 22 05 01 00 00 00 a0 7a a3 0b 00 70 00 00  .?".....?z?..p..
0x70000ba37710: e0 78 a3 0b 00 70 00 00 1d bb 0e 04 01 00 00 00  ?x?..p...?......

// continue, 之后 断点停留在了 第二个 monitorenter 
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 3.1
    frame #0: 0x000000010524f980
->  0x10524f980: popq   %rax
    0x10524f981: cmpq   (%rax), %rax
    0x10524f984: xorl   %esi, %esi
    0x10524f986: movq   -0x48(%rbp), %rcx
Target 0: (java) stopped.
(lldb) p ((oopDesc*)0x0000000747bb8798)->print()
com.hx.test04.Test26SynchronizeReentrantObject
{0x0000000747bb8798} - klass: 'com/hx/test04/Test26SynchronizeReentrantObject'
 - ---- fields (total size 5 words):
 - 'f01' 'I' @12  0
 - 'f02' 'I' @16  0
 - 'f03' 'I' @20  0
 - 'f04' 'I' @24  0
 - 'f05' 'I' @28  0
 - private 'identStr' 'Ljava/lang/String;' @32  "xyz"{0x0000000747bb87c0} (e8f770f8 0)
(lldb) p ((oopDesc*)0x0000000747bb8798)->mark()->biased_locker()->threadObj()->print()
java.lang.Thread
{0x0000000747f069d8} - klass: 'java/lang/Thread'
 - ---- fields (total size 47 words):
 - private 'priority' 'I' @12  5
 - private 'eetop' 'J' @16  4320157696 (1806000 1)
 - private 'stackSize' 'J' @24  0 (0 0)
 - private 'nativeParkEventPointer' 'J' @32  0 (0 0)
 - private 'tid' 'J' @40  1 (1 0)
 - private volatile 'threadStatus' 'I' @48  5
 - private 'single_step' 'Z' @52  false
 - private 'daemon' 'Z' @53  false
 - private 'stillborn' 'Z' @54  false
 - private volatile 'name' 'Ljava/lang/String;' @56  "main"{0x0000000747f06b50} (e8fe0d6a 0)
 - private 'threadQ' 'Ljava/lang/Thread;' @60  NULL (0 0)
 - private 'target' 'Ljava/lang/Runnable;' @64  NULL (0 e8fe0c85)
 - private 'group' 'Ljava/lang/ThreadGroup;' @68  a 'java/lang/ThreadGroup'{0x0000000747f06428} (e8fe0c85 e8fc0af7)
 - private 'contextClassLoader' 'Ljava/lang/ClassLoader;' @72  a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x0000000747e057b8} (e8fc0af7 e8fe0d91)
 - private 'inheritedAccessControlContext' 'Ljava/security/AccessControlContext;' @76  a 'java/security/AccessControlContext'{0x0000000747f06c88} (e8fe0d91 e8fe2fb8)
 - 'threadLocals' 'Ljava/lang/ThreadLocal$ThreadLocalMap;' @80  a 'java/lang/ThreadLocal$ThreadLocalMap'{0x0000000747f17dc0} (e8fe2fb8 0)
 - 'inheritableThreadLocals' 'Ljava/lang/ThreadLocal$ThreadLocalMap;' @84  NULL (0 0)
 - volatile 'parkBlocker' 'Ljava/lang/Object;' @88  NULL (0 0)
 - private volatile 'blocker' 'Lsun/nio/ch/Interruptible;' @92  NULL (0 e8fe0d70)
 - private final 'blockerLock' 'Ljava/lang/Object;' @96  a 'java/lang/Object'{0x0000000747f06b80} (e8fe0d70 0)
 - private volatile 'uncaughtExceptionHandler' 'Ljava/lang/Thread$UncaughtExceptionHandler;' @100  NULL (0 0)
 - 'threadLocalRandomSeed' 'J' @232  0 (0 0)
 - 'threadLocalRandomProbe' 'I' @240  0
 - 'threadLocalRandomSecondarySeed' 'I' @244  0
(lldb) x 0x0000000747bb8798
0x747bb8798: 05 60 80 01 01 00 00 00 86 1f 01 f8 00 00 00 00  .`.........?....
0x747bb87a8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
(lldb) re r
General Purpose Registers:
       rax = 0x0000000747bb8798
       rbx = 0x00000000000000c2
       rcx = 0x0000000747bb8798
       rdx = 0x000070000ba37628
       rdi = 0x0000000101806000
       rsi = 0x000070000ba37618
       rbp = 0x000070000ba37670
       rsp = 0x000070000ba37610
        r8 = 0x0000000000000000
        r9 = 0x0000000000000020
       r10 = 0x0000000104b0b270  libjvm.dylib`TemplateInterpreter::_active_table + 18432
       r11 = 0x00006fff0a229200
       r12 = 0x0000000000000000
       r13 = 0x000000011d1eff97
       r14 = 0x000070000ba376a8
       r15 = 0x0000000101806000
       rip = 0x000000010524f980
    rflags = 0x0000000000000202
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000
(lldb) x 0x000070000ba37610 -c 0x100
0x70000ba37610: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba37620: 98 87 bb 47 07 00 00 00 18 76 a3 0b 00 70 00 00  ..?G.....v?..p..
0x70000ba37630: 94 ff 1e 1d 01 00 00 00 a8 76 a3 0b 00 70 00 00  .?......?v?..p..
0x70000ba37640: 88 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba37650: 70 82 bb 47 07 00 00 00 00 00 1f 1d 01 00 00 00  p.?G............
0x70000ba37660: 00 00 00 00 00 00 00 00 a8 76 a3 0b 00 70 00 00  ........?v?..p..
0x70000ba37670: 10 77 a3 0b 00 70 00 00 f1 09 20 05 01 00 00 00  .w?..p..?. .....
0x70000ba37680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba37690: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba376a0: 98 87 bb 47 07 00 00 00 88 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba376b0: a0 1f 00 00 03 00 00 00 00 00 00 00 00 00 00 00  ?...............
0x70000ba376c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba376d0: 00 00 00 00 00 00 00 00 00 80 a3 0b 00 70 00 00  ..........?..p..
0x70000ba376e0: 20 78 a3 0b 00 70 00 00 50 7d a3 0b 00 70 00 00   x?..p..P}?..p..
0x70000ba376f0: 0a 00 00 00 00 70 00 00 00 00 1f 1d 01 00 00 00  .....p..........
0x70000ba37700: 00 a7 22 05 01 00 00 00 a0 7a a3 0b 00 70 00 00  .?".....?z?..p..

这里在 monitorenter 的地方打了一个断点, 并且输出了 当前 lockObj 的相关信息之后, 直接 continue, 断点停在了 第二个 monitorenter 

我们可以整理一些结论 

1. 在第一个断点的时候, lockObj 没有锁, 就一个 0x101, 第二个断点的时候 已经加上了偏向锁 偏向于 main 线程 

2. 第二个断点相比于 第一个断点, [0x70000ba37618 - 0x70000ba37628) 增加了一个 BasicLockObject 关联 lockObj 对象 

 

 

那么 我们接下来看一下 重入的情况 会走怎么样的流程呢 

分配了 BasicObjectLock 之后情况如下 

(lldb) b 0x10524f9dc
Breakpoint 4: address = 0x000000010524f9dc
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 4.1
    frame #0: 0x000000010524f9dc
->  0x10524f9dc: incq   %r13
    0x10524f9df: movq   %rax, 0x8(%rsi)
    0x10524f9e3: movq   0x8(%rsi), %rcx
    0x10524f9e7: movq   (%rcx), %rax
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000747bb8798
       rbx = 0x00000000000000c2
       rcx = 0x000070000ba37608
       rdx = 0x000070000ba37628
       rdi = 0x0000000101806000
       rsi = 0x000070000ba37608
       rbp = 0x000070000ba37670
       rsp = 0x000070000ba37608
        r8 = 0x0000000000000000
        r9 = 0x0000000000000020
       r10 = 0x0000000104b0b270  libjvm.dylib`TemplateInterpreter::_active_table + 18432
       r11 = 0x00006fff0a229200
       r12 = 0x0000000000000000
       r13 = 0x000000011d1eff97
       r14 = 0x000070000ba376a8
       r15 = 0x0000000101806000
       rip = 0x000000010524f9dc
    rflags = 0x0000000000000246
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000
(lldb) x 0x000070000ba37608 -c 0x100
0x70000ba37608: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba37618: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba37628: 08 76 a3 0b 00 70 00 00 94 ff 1e 1d 01 00 00 00  .v?..p...?......
0x70000ba37638: a8 76 a3 0b 00 70 00 00 88 00 1f 1d 01 00 00 00  ?v?..p..........
0x70000ba37648: 00 00 00 00 00 00 00 00 70 82 bb 47 07 00 00 00  ........p.?G....
0x70000ba37658: 00 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba37668: a8 76 a3 0b 00 70 00 00 10 77 a3 0b 00 70 00 00  ?v?..p...w?..p..
0x70000ba37678: f1 09 20 05 01 00 00 00 00 00 00 00 00 00 00 00  ?. .............
0x70000ba37688: 00 00 00 00 00 00 00 00 98 87 bb 47 07 00 00 00  ..........?G....
0x70000ba37698: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba376a8: 88 87 bb 47 07 00 00 00 a0 1f 00 00 03 00 00 00  ..?G....?.......
0x70000ba376b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba376c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba376d8: 00 80 a3 0b 00 70 00 00 20 78 a3 0b 00 70 00 00  ..?..p.. x?..p..
0x70000ba376e8: 50 7d a3 0b 00 70 00 00 0a 00 00 00 00 70 00 00  P}?..p.......p..
0x70000ba376f8: 00 00 1f 1d 01 00 00 00 00 a7 22 05 01 00 00 00  .........?".....

0x70000ba37628 : 标记点的是 expression bottom, 第二次 monitorenter 的时候是 0x000070000ba37618 
现在有多了一个 BasicLockObject 了, 变成了 0x000070000ba37608

 

加锁的流程如下 

(lldb) stepi -c 7
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010524f9f5
->  0x10524f9f5: jne    0x10524fa7c
    0x10524f9fb: movl   0x8(%rcx), %ebx
    0x10524f9fe: shlq   $0x3, %rbx
    0x10524fa02: movq   0xb0(%rbx), %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010524f9fb
->  0x10524f9fb: movl   0x8(%rcx), %ebx
    0x10524f9fe: shlq   $0x3, %rbx
    0x10524fa02: movq   0xb0(%rbx), %rbx
    0x10524fa09: orq    %r15, %rbx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000101806005
       rbx = 0x0000000000000005
       rcx = 0x0000000747bb8798
       rdx = 0x000070000ba37628
       rdi = 0x0000000101806000
       rsi = 0x000070000ba37608
       rbp = 0x000070000ba37670
       rsp = 0x000070000ba37608
        r8 = 0x0000000000000000
        r9 = 0x0000000000000020
       r10 = 0x0000000104b0b270  libjvm.dylib`TemplateInterpreter::_active_table + 18432
       r11 = 0x00006fff0a229200
       r12 = 0x0000000000000000
       r13 = 0x000000011d1eff98
       r14 = 0x000070000ba376a8
       r15 = 0x0000000101806000
       rip = 0x000000010524f9fb
    rflags = 0x0000000000000246
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) stepi 
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010524f9fe
->  0x10524f9fe: shlq   $0x3, %rbx
    0x10524fa02: movq   0xb0(%rbx), %rbx
    0x10524fa09: orq    %r15, %rbx
    0x10524fa0c: xorq   %rax, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010524fa02
->  0x10524fa02: movq   0xb0(%rbx), %rbx
    0x10524fa09: orq    %r15, %rbx
    0x10524fa0c: xorq   %rax, %rbx
    0x10524fa0f: andq   $-0x79, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010524fa09
->  0x10524fa09: orq    %r15, %rbx
    0x10524fa0c: xorq   %rax, %rbx
    0x10524fa0f: andq   $-0x79, %rbx
    0x10524fa13: je     0x10524fd05
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010524fa0c
->  0x10524fa0c: xorq   %rax, %rbx
    0x10524fa0f: andq   $-0x79, %rbx
    0x10524fa13: je     0x10524fd05
    0x10524fa19: testq  $0x7, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010524fa0f
->  0x10524fa0f: andq   $-0x79, %rbx
    0x10524fa13: je     0x10524fd05
    0x10524fa19: testq  $0x7, %rbx
    0x10524fa20: jne    0x10524fa69
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000101806005
       rbx = 0x0000000000000000
       rcx = 0x0000000747bb8798
       rdx = 0x000070000ba37628
       rdi = 0x0000000101806000
       rsi = 0x000070000ba37608
       rbp = 0x000070000ba37670
       rsp = 0x000070000ba37608
        r8 = 0x0000000000000000
        r9 = 0x0000000000000020
       r10 = 0x0000000104b0b270  libjvm.dylib`TemplateInterpreter::_active_table + 18432
       r11 = 0x00006fff0a229200
       r12 = 0x0000000000000000
       r13 = 0x000000011d1eff98
       r14 = 0x000070000ba376a8
       r15 = 0x0000000101806000
       rip = 0x000000010524fa0f
    rflags = 0x0000000000000246
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010524fa13
->  0x10524fa13: je     0x10524fd05
    0x10524fa19: testq  $0x7, %rbx
    0x10524fa20: jne    0x10524fa69
    0x10524fa22: testq  $0x300, %rbx              ; imm = 0x300 
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010524fd05
->  0x10524fd05: movq   %r13, -0x40(%rbp)
    0x10524fd09: movl   %eax, -0x16000(%rsp)
    0x10524fd10: movzbl (%r13), %ebx
    0x10524fd15: movabsq $0x104b0b270, %r10        ; imm = 0x104B0B270 
Target 0: (java) stopped.

发现当前线程 和 偏向锁上面记录的线程, epoch 一样, 直接 加锁完成 

 

 

偏向锁的退出 

(lldb) p _active_table._table[9][195]
(address) $1 = 0x000000010524fde0 "XH;"
(lldb) b 0x000000010524fde1
Breakpoint 5: address = 0x000000010524fde1
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 5.1
    frame #0: 0x000000010524fde1
->  0x10524fde1: cmpq   (%rax), %rax
    0x10524fde4: movq   -0x48(%rbp), %rsi
    0x10524fde8: leaq   -0x48(%rbp), %rdx
    0x10524fdec: jmp    0x10524fdfc
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000747bb8798
       rbx = 0x00000000000000c3
       rcx = 0x0000000747bb8798
       rdx = 0x000070000ba37628
       rdi = 0x0000000101806000
       rsi = 0x000070000ba37608
       rbp = 0x000070000ba37670
       rsp = 0x000070000ba37608
        r8 = 0x0000000000000000
        r9 = 0x0000000000000020
       r10 = 0x0000000104b0aa70  libjvm.dylib`TemplateInterpreter::_active_table + 16384
       r11 = 0x00006fff0a229200
       r12 = 0x0000000000000000
       r13 = 0x000000011d1eff99
       r14 = 0x000070000ba376a8
       r15 = 0x0000000101806000
       rip = 0x000000010524fde1
    rflags = 0x0000000000000206
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) p ((oopDesc*)0x0000000747bb8798)->print()
com.hx.test04.Test26SynchronizeReentrantObject
{0x0000000747bb8798} - klass: 'com/hx/test04/Test26SynchronizeReentrantObject'
 - ---- fields (total size 5 words):
 - 'f01' 'I' @12  0
 - 'f02' 'I' @16  0
 - 'f03' 'I' @20  0
 - 'f04' 'I' @24  0
 - 'f05' 'I' @28  0
 - private 'identStr' 'Ljava/lang/String;' @32  "xyz"{0x0000000747bb87c0} (e8f770f8 0)
(lldb) x 0x000070000ba37608 -c 0x100
0x70000ba37608: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba37618: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba37628: 08 76 a3 0b 00 70 00 00 98 ff 1e 1d 01 00 00 00  .v?..p...?......
0x70000ba37638: a8 76 a3 0b 00 70 00 00 88 00 1f 1d 01 00 00 00  ?v?..p..........
0x70000ba37648: 00 00 00 00 00 00 00 00 70 82 bb 47 07 00 00 00  ........p.?G....
0x70000ba37658: 00 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba37668: a8 76 a3 0b 00 70 00 00 10 77 a3 0b 00 70 00 00  ?v?..p...w?..p..
0x70000ba37678: f1 09 20 05 01 00 00 00 00 00 00 00 00 00 00 00  ?. .............
0x70000ba37688: 00 00 00 00 00 00 00 00 98 87 bb 47 07 00 00 00  ..........?G....
0x70000ba37698: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba376a8: 88 87 bb 47 07 00 00 00 a0 1f 00 00 03 00 00 00  ..?G....?.......
0x70000ba376b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba376c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba376d8: 00 80 a3 0b 00 70 00 00 20 78 a3 0b 00 70 00 00  ..?..p.. x?..p..
0x70000ba376e8: 50 7d a3 0b 00 70 00 00 0a 00 00 00 00 70 00 00  P}?..p.......p..
0x70000ba376f8: 00 00 1f 1d 01 00 00 00 00 a7 22 05 01 00 00 00  .........?".....

// continue, 之后 断点停留在了 第二个 monitorexit 
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 5.1
    frame #0: 0x000000010524fde1
->  0x10524fde1: cmpq   (%rax), %rax
    0x10524fde4: movq   -0x48(%rbp), %rsi
    0x10524fde8: leaq   -0x48(%rbp), %rdx
    0x10524fdec: jmp    0x10524fdfc
Target 0: (java) stopped.
(lldb) x 0x000070000ba37608 -c 0x100
0x70000ba37608: 98 87 bb 47 07 00 00 00 00 00 00 00 00 00 00 00  ..?G............
0x70000ba37618: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba37628: 08 76 a3 0b 00 70 00 00 99 ff 1e 1d 01 00 00 00  .v?..p...?......
0x70000ba37638: a8 76 a3 0b 00 70 00 00 88 00 1f 1d 01 00 00 00  ?v?..p..........
0x70000ba37648: 00 00 00 00 00 00 00 00 70 82 bb 47 07 00 00 00  ........p.?G....
0x70000ba37658: 00 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba37668: a8 76 a3 0b 00 70 00 00 10 77 a3 0b 00 70 00 00  ?v?..p...w?..p..
0x70000ba37678: f1 09 20 05 01 00 00 00 00 00 00 00 00 00 00 00  ?. .............
0x70000ba37688: 00 00 00 00 00 00 00 00 98 87 bb 47 07 00 00 00  ..........?G....
0x70000ba37698: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba376a8: 88 87 bb 47 07 00 00 00 a0 1f 00 00 03 00 00 00  ..?G....?.......
0x70000ba376b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba376c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba376d8: 00 80 a3 0b 00 70 00 00 20 78 a3 0b 00 70 00 00  ..?..p.. x?..p..
0x70000ba376e8: 50 7d a3 0b 00 70 00 00 0a 00 00 00 00 70 00 00  P}?..p.......p..
0x70000ba376f8: 00 00 1f 1d 01 00 00 00 00 a7 22 05 01 00 00 00  .........?".....
(lldb) b 0x1052500ec
Breakpoint 6: address = 0x00000001052500ec
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 6.1
    frame #0: 0x00000001052500ec
->  0x1052500ec: movq   (%rcx), %rdx
    0x1052500ef: andq   $0x7, %rdx
    0x1052500f3: cmpq   $0x5, %rdx
    0x1052500f7: je     0x105250378
Target 0: (java) stopped.
(lldb) stepi -c 3
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x00000001052500f7
->  0x1052500f7: je     0x105250378
    0x1052500fd: movq   (%rax), %rdx
    0x105250100: testq  %rdx, %rdx
    0x105250103: je     0x105250378
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105250378
->  0x105250378: movq   -0x40(%rbp), %r13
    0x10525037c: popq   %rax
    0x10525037d: movzbl 0x1(%r13), %ebx
    0x105250382: incq   %r13
Target 0: (java) stopped.
(lldb) x 0x000070000ba37608 -c 0x100
0x70000ba37608: 98 87 bb 47 07 00 00 00 00 00 00 00 00 00 00 00  ..?G............
0x70000ba37618: 98 87 bb 47 07 00 00 00 00 00 00 00 00 00 00 00  ..?G............
0x70000ba37628: 08 76 a3 0b 00 70 00 00 a5 ff 1e 1d 01 00 00 00  .v?..p..??......
0x70000ba37638: a8 76 a3 0b 00 70 00 00 88 00 1f 1d 01 00 00 00  ?v?..p..........
0x70000ba37648: 00 00 00 00 00 00 00 00 70 82 bb 47 07 00 00 00  ........p.?G....
0x70000ba37658: 00 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba37668: a8 76 a3 0b 00 70 00 00 10 77 a3 0b 00 70 00 00  ?v?..p...w?..p..
0x70000ba37678: f1 09 20 05 01 00 00 00 00 00 00 00 00 00 00 00  ?. .............
0x70000ba37688: 00 00 00 00 00 00 00 00 98 87 bb 47 07 00 00 00  ..........?G....
0x70000ba37698: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00  ..?G......?G....
0x70000ba376a8: 88 87 bb 47 07 00 00 00 a0 1f 00 00 03 00 00 00  ..?G....?.......
0x70000ba376b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba376c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000ba376d8: 00 80 a3 0b 00 70 00 00 20 78 a3 0b 00 70 00 00  ..?..p.. x?..p..
0x70000ba376e8: 50 7d a3 0b 00 70 00 00 0a 00 00 00 00 70 00 00  P}?..p.......p..
0x70000ba376f8: 00 00 1f 1d 01 00 00 00 00 a7 22 05 01 00 00 00  .........?".....

可以看到这里的两次偏向锁的退出 主要的事情是 吧对应的 BasicLockObject.obj 置空处理(一则是标记obj已经不持有锁了, 二则是其他的对象可以复用) 

 

 

偏向线程同步块执行完成 非偏向线程尝试加锁

package com.hx.test04;

/**
 * Test27MultiThreadInBiasLock
 *
 * @author Jerry.X.He <[email protected]>
 * @version 1.0
 * @date 2020-04-03 15:14
 */
public class Test27MultiThreadInBiasLock implements Cloneable {

  // identStr
  private String identStr = "xyz";
  int f01;
  int f02;
  int f03;
  int f04;
  int f05;

  // Test25SynchronizeObject
  public static void main(String[] args) throws Exception {

    Test27MultiThreadInBiasLock lockObj = new Test27MultiThreadInBiasLock();

    doClone(lockObj);
    synchronized (lockObj) {

    }

    new Thread() {
      @Override
      public void run() {
        doClone(lockObj);
        synchronized (lockObj) {

        }
      }
    }.start();

    Test25SynchronizeObject.sleep(2000);
  }

  // doClone
  private static void doClone(Test27MultiThreadInBiasLock obj) {
    try {
      obj.clone();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

}

 

lldb 调试如下 

(lldb) p _active_table._table[9][194]
(address) $0 = 0x000000010584f980 "XH;"
(lldb) c
Process 2916 resuming
Process 2916 stopped
* thread #5, stop reason = breakpoint 3.1
    frame #0: 0x0000000103171ab4 libjvm.dylib`::JVM_Clone(env=0x0000000101008a28, handle=0x000070000f2635c8) at jvm.cpp:627:28
   624 	JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
   625 	  JVMWrapper("JVM_Clone");
   626 	  Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
-> 627 	  const KlassHandle klass (THREAD, obj->klass());
   628 	  JvmtiVMObjectAllocEventCollector oam;
   629 	
   630 	#ifdef ASSERT
Target 0: (java) stopped.

(lldb) c
Process 2916 resuming
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = breakpoint 3.1
    frame #0: 0x0000000103171ab4 libjvm.dylib`::JVM_Clone(env=0x0000000101054228, handle=0x00007000113c65e0) at jvm.cpp:627:28
   624 	JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
   625 	  JVMWrapper("JVM_Clone");
   626 	  Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
-> 627 	  const KlassHandle klass (THREAD, obj->klass());
   628 	  JvmtiVMObjectAllocEventCollector oam;
   629 	
   630 	#ifdef ASSERT
Target 0: (java) stopped.

(lldb) b 0x000000010584f980
Breakpoint 4: address = 0x000000010584f980
(lldb) c
Process 2916 resuming
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = breakpoint 4.1
    frame #0: 0x000000010584f980
->  0x10584f980: popq   %rax
    0x10584f981: cmpq   (%rax), %rax
    0x10584f984: xorl   %esi, %esi
    0x10584f986: movq   -0x48(%rbp), %rcx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000747bb8ec0
       rbx = 0x00000000000000c2
       rcx = 0x00000000000000cb
       rdx = 0x0000000000000000
       rdi = 0x000000010580b220
       rsi = 0x00007000113c6650
       rbp = 0x00007000113c66f8
       rsp = 0x00007000113c66a8
        r8 = 0x0000000000000000
        r9 = 0x0000000100315a90
       r10 = 0x0000000103b0b270  libjvm.dylib`TemplateInterpreter::_active_table + 18432
       r11 = 0x00007000113c65e0
       r12 = 0x0000000000000000
       r13 = 0x000000011d46f845
       r14 = 0x00007000113c6718
       r15 = 0x0000000101054000
       rip = 0x000000010584f980
    rflags = 0x0000000000000202
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) p ((oopDesc*)0x0000000747bb8ec0)->print()
com.hx.test04.Test27MultiThreadInBiasLock 
{0x0000000747bb8ec0} - klass: 'com/hx/test04/Test27MultiThreadInBiasLock'
 - ---- fields (total size 5 words):
 - 'f01' 'I' @12  0
 - 'f02' 'I' @16  0
 - 'f03' 'I' @20  0
 - 'f04' 'I' @24  0
 - 'f05' 'I' @28  0
 - private 'identStr' 'Ljava/lang/String;' @32  "xyz"{0x0000000747bb8ee8} (e8f771dd 0)
(lldb) p ((oopDesc*)0x0000000747bb8ec0)->mark()->biased_locker()->threadObj()->print()
java.lang.Thread 
{0x0000000747f069d8} - klass: 'java/lang/Thread'
 - ---- fields (total size 47 words):
 - private 'priority' 'I' @12  5
 - private 'eetop' 'J' @16  4311779328 (1008800 1)
 - private 'stackSize' 'J' @24  0 (0 0)
 - private 'nativeParkEventPointer' 'J' @32  0 (0 0)
 - private 'tid' 'J' @40  1 (1 0)
 - private volatile 'threadStatus' 'I' @48  5
 - private 'single_step' 'Z' @52  false
 - private 'daemon' 'Z' @53  false
 - private 'stillborn' 'Z' @54  false
 - private volatile 'name' 'Ljava/lang/String;' @56  "main"{0x0000000747f06b50} (e8fe0d6a 0)
 - private 'threadQ' 'Ljava/lang/Thread;' @60  NULL (0 0)
 - private 'target' 'Ljava/lang/Runnable;' @64  NULL (0 e8fe0c85)
 - private 'group' 'Ljava/lang/ThreadGroup;' @68  a 'java/lang/ThreadGroup'{0x0000000747f06428} (e8fe0c85 e8fc0af7)
 - private 'contextClassLoader' 'Ljava/lang/ClassLoader;' @72  a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x0000000747e057b8} (e8fc0af7 e8fe0d91)
 - private 'inheritedAccessControlContext' 'Ljava/security/AccessControlContext;' @76  a 'java/security/AccessControlContext'{0x0000000747f06c88} (e8fe0d91 e8fe2fb8)
 - 'threadLocals' 'Ljava/lang/ThreadLocal$ThreadLocalMap;' @80  a 'java/lang/ThreadLocal$ThreadLocalMap'{0x0000000747f17dc0} (e8fe2fb8 0)
 - 'inheritableThreadLocals' 'Ljava/lang/ThreadLocal$ThreadLocalMap;' @84  NULL (0 0)
 - volatile 'parkBlocker' 'Ljava/lang/Object;' @88  NULL (0 0)
 - private volatile 'blocker' 'Lsun/nio/ch/Interruptible;' @92  NULL (0 e8fe0d70)
 - private final 'blockerLock' 'Ljava/lang/Object;' @96  a 'java/lang/Object'{0x0000000747f06b80} (e8fe0d70 0)
 - private volatile 'uncaughtExceptionHandler' 'Ljava/lang/Thread$UncaughtExceptionHandler;' @100  NULL (0 0)
 - 'threadLocalRandomSeed' 'J' @232  0 (0 0)
 - 'threadLocalRandomProbe' 'I' @240  0
 - 'threadLocalRandomSecondarySeed' 'I' @244  0
(lldb) b 0x10584f9e3
Breakpoint 5: address = 0x000000010584f9e3
(lldb) c
Process 2916 resuming
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = breakpoint 5.1
    frame #0: 0x000000010584f9e3
->  0x10584f9e3: movq   0x8(%rsi), %rcx
    0x10584f9e7: movq   (%rcx), %rax
    0x10584f9ea: movq   %rax, %rbx
    0x10584f9ed: andq   $0x7, %rbx
Target 0: (java) stopped.
(lldb) stepi -c 4
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584f9f1
->  0x10584f9f1: cmpq   $0x5, %rbx
    0x10584f9f5: jne    0x10584fa7c
    0x10584f9fb: movl   0x8(%rcx), %ebx
    0x10584f9fe: shlq   $0x3, %rbx
Target 0: (java) stopped.
(lldb) stepi 
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584f9f5
->  0x10584f9f5: jne    0x10584fa7c
    0x10584f9fb: movl   0x8(%rcx), %ebx
    0x10584f9fe: shlq   $0x3, %rbx
    0x10584fa02: movq   0xb0(%rbx), %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584f9fb
->  0x10584f9fb: movl   0x8(%rcx), %ebx
    0x10584f9fe: shlq   $0x3, %rbx
    0x10584fa02: movq   0xb0(%rbx), %rbx
    0x10584fa09: orq    %r15, %rbx
Target 0: (java) stopped.
(lldb) stepi -c 4
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa0c
->  0x10584fa0c: xorq   %rax, %rbx
    0x10584fa0f: andq   $-0x79, %rbx
    0x10584fa13: je     0x10584fd05
    0x10584fa19: testq  $0x7, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa0f
->  0x10584fa0f: andq   $-0x79, %rbx
    0x10584fa13: je     0x10584fd05
    0x10584fa19: testq  $0x7, %rbx
    0x10584fa20: jne    0x10584fa69
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa13
->  0x10584fa13: je     0x10584fd05
    0x10584fa19: testq  $0x7, %rbx
    0x10584fa20: jne    0x10584fa69
    0x10584fa22: testq  $0x300, %rbx              ; imm = 0x300 
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa19
->  0x10584fa19: testq  $0x7, %rbx
    0x10584fa20: jne    0x10584fa69
    0x10584fa22: testq  $0x300, %rbx              ; imm = 0x300 
    0x10584fa29: jne    0x10584fa48
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa20
->  0x10584fa20: jne    0x10584fa69
    0x10584fa22: testq  $0x300, %rbx              ; imm = 0x300 
    0x10584fa29: jne    0x10584fa48
    0x10584fa2b: andq   $0x37f, %rax              ; imm = 0x37F 
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa22
->  0x10584fa22: testq  $0x300, %rbx              ; imm = 0x300 
    0x10584fa29: jne    0x10584fa48
    0x10584fa2b: andq   $0x37f, %rax              ; imm = 0x37F 
    0x10584fa32: movq   %rax, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa29
->  0x10584fa29: jne    0x10584fa48
    0x10584fa2b: andq   $0x37f, %rax              ; imm = 0x37F 
    0x10584fa32: movq   %rax, %rbx
    0x10584fa35: orq    %r15, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa2b
->  0x10584fa2b: andq   $0x37f, %rax              ; imm = 0x37F 
    0x10584fa32: movq   %rax, %rbx
    0x10584fa35: orq    %r15, %rbx
    0x10584fa38: lock   
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa32
->  0x10584fa32: movq   %rax, %rbx
    0x10584fa35: orq    %r15, %rbx
    0x10584fa38: lock   
    0x10584fa39: cmpxchgq %rbx, (%rcx)
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa35
->  0x10584fa35: orq    %r15, %rbx
    0x10584fa38: lock   
    0x10584fa39: cmpxchgq %rbx, (%rcx)
    0x10584fa3d: jne    0x10584faa5
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa38
->  0x10584fa38: lock   
    0x10584fa39: cmpxchgq %rbx, (%rcx)
    0x10584fa3d: jne    0x10584faa5
    0x10584fa43: jmp    0x10584fd05
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584fa3d
->  0x10584fa3d: jne    0x10584faa5
    0x10584fa43: jmp    0x10584fd05
    0x10584fa48: movl   0x8(%rcx), %ebx
    0x10584fa4b: shlq   $0x3, %rbx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000101008805
       rbx = 0x0000000101054005
       rcx = 0x0000000747bb8ec0
       rdx = 0x00007000113c66b0
       rdi = 0x000000010580b220
       rsi = 0x00007000113c66a0
       rbp = 0x00007000113c66f8
       rsp = 0x00007000113c66a0
        r8 = 0x0000000000000000
        r9 = 0x0000000100315a90
       r10 = 0x0000000103b0b270  libjvm.dylib`TemplateInterpreter::_active_table + 18432
       r11 = 0x00007000113c65e0
       r12 = 0x0000000000000000
       r13 = 0x000000011d46f846
       r14 = 0x00007000113c6718
       r15 = 0x0000000101054000
       rip = 0x000000010584fa3d
    rflags = 0x0000000000000287
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
    frame #0: 0x000000010584faa5
->  0x10584faa5: callq  0x10584faaf
    0x10584faaa: jmp    0x10584fd05
    0x10584faaf: leaq   0x8(%rsp), %rax
    0x10584fab4: movq   %r13, -0x40(%rbp)
Target 0: (java) stopped.

到 monitorenter 的代码的时候, lockObj 的偏向锁已经偏向于 main 线程, 并且 main 线程已经退出了 同步代码块 

然后 Thread-0 走同步的流程, 申请 BasicLockObject, 然后创建  走的是 正常更新偏向锁的流程, 但是 由于 lockObj 的偏向锁已经偏向于 main 线程, 因此 cas 更新 mark 的时候失败了, 之后 走的 InterpreterRuntime::monitorenter 的流程 

然后 这部分的处理, 在这里 就不展开了 

 

 

偏向锁可以 偏向线程1 之后 偏向线程2 么?

11 偏向锁的重入 以及 线程1获取偏向锁并释放线程2获取锁 的调试_第1张图片

撤销偏向锁的调用的地方  

11 偏向锁的重入 以及 线程1获取偏向锁并释放线程2获取锁 的调试_第2张图片

上面第二行传入 变量的方法, 调用的地方 

11 偏向锁的重入 以及 线程1获取偏向锁并释放线程2获取锁 的调试_第3张图片

上面第二行传入 变量的方法, 调用的地方, 可能是 true, 这个方法是 BiasedLocking::revoke_and_rebias 

11 偏向锁的重入 以及 线程1获取偏向锁并释放线程2获取锁 的调试_第4张图片

只有在 synchronizer.cpp 里面的 fast_enter 方法里面可能传入 true 

但是 就算是这里传入的是 true, 后面创建了 批量Rebias 的 VMOperation, operation 里面返回的状态也是 BiasedLocking::BIAS_REVOKED, 后面还是走 锁升级 的处理 

 

所以 应该是不会出现这种情况, 存在竞争 锁会 inflate 

 

 

完 

 

 

参考 

09 给对象添加偏向锁的调试

10 偏向锁的退出的调试

 

 

你可能感兴趣的:(11,HotspotVM)