首先编写一段代码将三种使用synchronized的形式都包含在里面
在反编译看看助记符代码
public class syschoriznizedbytecodetest {
Object a;
public static synchronized void test1(){
System.out.println("static synchrozied");
}
public synchronized void test2(){
System.out.println("nostatic method syschronized");
}
public void test3(){
synchronized (a){
System.out.println("code block test");
}
}
}
我将一部分常量池和方法的一些代码删掉了,我们只看这几个测试方法
public static synchronized void test1();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=0, args_size=0
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String static synchrozied
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 6: 0
line 7: 8
public synchronized void test2();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #5 // String nostatic method syschronized
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 9: 0
line 10: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Lcom/nettylearn/Service/binarycode/syschoriznizedbytecodetest;
public void test3();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: aload_0
1: getfield #6 // Field a:Ljava/lang/Object;
4: dup
5: astore_1
6: monitorenter
7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
10: ldc #7 // String code block test
12: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
15: aload_1
16: monitorexit
17: goto 25
20: astore_2
21: aload_1
22: monitorexit
23: aload_2
24: athrow
25: return
Exception table:
from to target type
7 17 20 any
20 23 20 any
LineNumberTable:
line 12: 0
line 13: 7
line 14: 15
line 15: 25
LocalVariableTable:
Start Length Slot Name Signature
0 26 0 this Lcom/nettylearn/Service/binarycode/syschoriznizedbytecodetest;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 20
locals = [ class com/nettylearn/Service/binarycode/syschoriznizedbytecodetest, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = 250 /* chop */
offset_delta = 4
}
SourceFile: "syschoriznizedbytecodetest.java"
我们可以发现前两种方式在字节码上面只是对方法的标示添加了synchronized这个标记,而最后一个代码块的方式我们就可以很清晰的看到它使用了monitorenter和monitorexit两个操作命令。
而且对于monitorexit还使用了两次,这是因为如果我们使用了print的io操作在io操作时可能会发生错误所以系统为我们加了一个额外的monitorexit因为如果出了错误就不会走到我们自己通过synchronized所产的那个monitorexit了,而且这里面有一个goto命令也就是说如果没有错误就会goto到return命令。