java同步: why instructions monitorenter and monitorexit does not appear in pairs in my example?

标签 java synchronization

我试图找出关键字syncronized在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通过使用monitorentermonitorexit在java中工作>。但是我不知道为什么只有1个monitorenter却有2个monitorexit,它们不是成对的

最佳答案

只有一种方法可以进入同步块(synchronized block):通过通向同步块(synchronized block)的顺序执行路径。这就是为什么您会看到一条 monitorenter 指令。

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

关于java同步: why instructions monitorenter and monitorexit does not appear in pairs in my example?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46762863/

相关文章:

Android 测试 - 如何同步 AsyncTask

java - 此类中引用的 Map 是否安全发布?

java - 如何根据对象的实例调用它来序列化函数,如果在线程中调用相同的实例则进行序列化,否则不进行序列化

java - 泽西 HTTP 身份验证 :How Can I Access and the HTTP authentication in jersey restful url?

java - 计算 Protocol Buffer 文件中的消息数

java - JUnit4 fail() 在这里,但是 pass() 在哪里?

java - ConcurrentHashMap 是否可以允许比并发级别更多的线程数?

java - 为什么我们需要在同一个对象上同步 notify() 才能工作

java - Chromedriver 在 Jenkins (Linux) 上失败

java - 如何让导入的图片短暂显示?