方法签名中带有或不带有同步关键字的方法的相同字节码

dkb*_*dkb 2 java bytecode synchronized

对于以下两个类,它们具有相同的Java字节码。

Java版本:

Java版本“ 1.8.0_181” Java™SE运行时环境(内部版本1.8.0_181-b13)Java HotSpot(TM)64位服务器VM(内部版本25.181-b13,混合模式)

javac和javap版本:

1.8.0_181

我的疑问是

  1. 不应法同步关键字有不同的字节码,我们可以看到在synchronized块中monitorentermonitorexit,或让我们假设我不应该混合synchronized块synchronized方法

  2. JVM如何以不同方式处理这两种方法?

    public class MySingleton1 {
    
    private MySingleton1() {}
    
    private static MySingleton1 ourInstance;
    
    public static MySingleton1 getInstance() {
        if (ourInstance == null) {
            ourInstance = new MySingleton1();
        }
        return ourInstance;
    }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    public class MySingleton2 {
    
    private MySingleton2() {}
    
    private static MySingleton2 ourInstance;
    
    public static synchronized MySingleton2 getInstance() {
        if (ourInstance == null) {
            ourInstance = new MySingleton2();
        }
        return ourInstance;
    }
    }
    
    Run Code Online (Sandbox Code Playgroud)

字节码如下:

$javac MySingleton1.java
$javap -c MySingleton1
$javac MySingleton2.java
$javap -c MySingleton2
Run Code Online (Sandbox Code Playgroud)

各个文件的字节码:

Compiled from "MySingleton1.java"
public class MySingleton1 {
  public static MySingleton1 getInstance();
    descriptor: ()LMySingleton1;
    Code:
       0: getstatic     #2                  // Field ourInstance:LMySingleton1;
       3: ifnonnull     16
       6: new           #3                  // class MySingleton1
       9: dup
      10: invokespecial #4                  // Method "<init>":()V
      13: putstatic     #2                  // Field ourInstance:LMySingleton1;
      16: getstatic     #2                  // Field ourInstance:LMySingleton1;
      19: areturn
}
Run Code Online (Sandbox Code Playgroud)

Compiled from "MySingleton2.java"
public class MySingleton2 {
  public static synchronized MySingleton2 getInstance();
    descriptor: ()LMySingleton2;
    Code:
       0: getstatic     #2                  // Field ourInstance:LMySingleton2;
       3: ifnonnull     16
       6: new           #3                  // class MySingleton2
       9: dup
      10: invokespecial #4                  // Method "<init>":()V
      13: putstatic     #2                  // Field ourInstance:LMySingleton2;
      16: getstatic     #2                  // Field ourInstance:LMySingleton2;
      19: areturn
}
Run Code Online (Sandbox Code Playgroud)

我只是想增加我对java wrt字节码的了解。

如果我的方法错误或问题太琐碎,请以评论的形式告诉我。

除以下内容外,任何与文档相关的参考文献都非常受欢迎:

https://zh.wikipedia.org/wiki/Java_bytecode

https://zh.wikipedia.org/wiki/Java_bytecode_instruction_listings

http://www.cnblogs.com/richaaaard/p/6214929.html

yol*_*ole 6

synchronized对方法改性剂被编译成在所述方法中报头中的ACC_SYNCHRONIZED标志。它不影响生成的字节码指令;JVM看到该标志时,会隐式添加进入和退出监视器的代码。

有关方法标题中标志的完整列表及其含义,请参见JVM规范