Same bytecode for method with or without synchronized keyword in method signature

痞子三分冷 提交于 2021-02-05 06:56:25

问题


For the following 2 classes got the same Java bytecode.

java version:

java version "1.8.0_181" Java(TM) SE Runtime Environment (build 1.8.0_181-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

javac and javap version:

1.8.0_181

My doubt is

  1. shouldn't method with synchronized keyword have different bytecode as we can see in synchronized block has monitorenter and monitorexit, or let us assume I should not mix synchronized block and synchronized method then

  2. How does JVM handle both methods differently?

    public class MySingleton1 {
    
    private MySingleton1() {}
    
    private static MySingleton1 ourInstance;
    
    public static MySingleton1 getInstance() {
        if (ourInstance == null) {
            ourInstance = new MySingleton1();
        }
        return ourInstance;
    }
    }
    

    and

    public class MySingleton2 {
    
    private MySingleton2() {}
    
    private static MySingleton2 ourInstance;
    
    public static synchronized MySingleton2 getInstance() {
        if (ourInstance == null) {
            ourInstance = new MySingleton2();
        }
        return ourInstance;
    }
    }
    

Bytecode as follows:

$javac MySingleton1.java
$javap -c MySingleton1
$javac MySingleton2.java
$javap -c MySingleton2

Bytecodes for respective files:

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
}

and

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
}

I just want to increase my understanding of java w.r.t. bytecode.

Let me know as comments if my approach is wrong or if a question is too trivial.

Any reference related to documentation is most welcome except the following:

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

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

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


回答1:


The synchronized modifier on the method is compiled into the ACC_SYNCHRONIZED flag in the method header. It does not affect the generated bytecode instructions; the code to enter and exit the monitor is added implicitly by the JVM when it sees that flag.

See the JVM specification for the complete list of flags in the method header and their meaning.



来源:https://stackoverflow.com/questions/52892370/same-bytecode-for-method-with-or-without-synchronized-keyword-in-method-signatur

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!