java syncronized:为什么指令monitorenter和monitorexit在我的例子中没有成对出现?

时间:2017-10-16 04:15:44

标签: java synchronization

我试图了解关键字同步如何在java内部工作。所以我写了一个非常简单的例子,并使用 javap 来查看字节码。

SyncTest.java

public class SyncTest {

   public void sort(int[] array) {
       synchronized(this) {
       }
   }
}

执行javac和javap

F:\>javac SyncTest.java

F:\>javap -c SyncTest.class
Compiled from "SyncTest.java"
public class SyncTest {
  public SyncTest();
  Code:
    0: aload_0
    1: invokespecial #1                  // Method java/lang/Object."<init>":()V
    4: return

public void sort(int[]);
Code:
   0: aload_0
   1: dup
   2: astore_2
   3: monitorenter
   4: aload_2
   5: monitorexit
   6: goto          14
   9: astore_3
  10: aload_2
  11: monitorexit
  12: aload_3
  13: athrow
  14: return
 Exception table:
   from    to  target type
       4     6     9   any
       9    12     9   any
}

enter image description here

从上面的字节代码段中,我发现syncronized在java中使用 monitorenter monitorexit 。但是, 我不知道为什么只有1个monitorenter但是2个monitorexit,它们不是成对的

1 个答案:

答案 0 :(得分:1)

只有一种方法可以进入同步块:通过引入同步块的顺序执行路径。这就是为什么你看到一条monitorenter指令的原因。

然而,有两条执行路径离开同步块:通过同步块末尾的顺序执行路径或(如果抛出异常)到某处的异常处理程序。因此,您有两条monitorexit指令:一条用于顺序路径(在偏移量为5),另一条用于异常路径(在偏移量为11)。