问题
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
shouldn't method with synchronized keyword have different bytecode as we can see in synchronized block has
monitorenter
andmonitorexit
, or let us assume I should not mix synchronized block and synchronized method thenHow 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