我试图了解关键字同步如何在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
}
从上面的字节代码段中,我发现syncronized在java中使用 monitorenter 和 monitorexit 。但是, 我不知道为什么只有1个monitorenter但是2个monitorexit,它们不是成对的 。
答案 0 :(得分:1)
只有一种方法可以进入同步块:通过引入同步块的顺序执行路径。这就是为什么你看到一条monitorenter
指令的原因。
然而,有两条执行路径离开同步块:通过同步块末尾的顺序执行路径或(如果抛出异常)到某处的异常处理程序。因此,您有两条monitorexit
指令:一条用于顺序路径(在偏移量为5),另一条用于异常路径(在偏移量为11)。