2017-10-16 10 views
0

我试图找出关键字同步在java内部工作。于是我写了一个非常简单的例子,并使用javap来查看字节码。【java syncronized】为什么说明monitorenter和monitorexit不会在我的例子中成对出现?

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

从上面的字节代码SEG我发现syncronized正在用java工作,使用monitorentermonitorexit。然而,我不知道为什么只有1 monitorenter,但2 monitorexit,他们不成对

有人可以帮助我吗?谢谢。

+0

你跟踪汇编代码吗?你的字节码中有一个跳转“goto”。 – chrylis

回答

0

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

但是,有两个执行路径会离开同步块:或者是由同步块末尾的顺序执行路径或(如果抛出异常)到达某处的异常处理程序。因此,您有两条monitorexit指令:一条用于顺序路径(偏移5),另一条用于异常路径(偏移11)。

相关问题