首先編寫一段代碼將三種使用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命令。