[英]jvm differences between synchronized and non-synchronized methods
我有以下課程:
public class SeqGenerator {
int last = 0;
volatile int lastVolatile = 0;
public int getNext() {
return last++;
}
public synchronized int getNextSync() {
return last++;
}
public int getNextVolatile() {
return lastVolatile++;
}
public void caller() {
int i1 = getNext();
int i2 = getNextSync();
int i3 = getNextVolatile();
}
}
當我查看反匯編代碼時,我沒有看到三個方法getNext()
, getNextSync()
和getNextVolatile()
的表示之間的區別。
public int getNext();
Code:
0: aload_0
1: dup
2: getfield #2; //Field last:I
5: dup_x1
6: iconst_1
7: iadd
8: putfield #2; //Field last:I
11: ireturn
public synchronized int getNextSync();
Code:
0: aload_0
1: dup
2: getfield #2; //Field last:I
5: dup_x1
6: iconst_1
7: iadd
8: putfield #2; //Field last:I
11: ireturn
public int getNextVolatile();
Code:
0: aload_0
1: dup
2: getfield #3; //Field lastVolatile:I
5: dup_x1
6: iconst_1
7: iadd
8: putfield #3; //Field lastVolatile:I
11: ireturn
public void caller();
Code:
0: aload_0
1: invokevirtual #4; //Method getNext:()I
4: istore_1
5: aload_0
6: invokevirtual #5; //Method getNextSync:()I
9: istore_2
10: aload_0
11: invokevirtual #6; //Method getNextVolatile:()I
14: istore_3
15: return
JMV如何區分這些方法?
生成的代碼與這些方法以及它們的調用者相同。 JVM如何執行同步?
應用於方法的synchronized
關鍵字僅在該方法定義上設置ACC_SYNCHRONIZED
標志,如JVM規范 ACC_SYNCHRONIZED
方法中所定義。 它在方法的實際字節碼中不可見。
JLS§8.4.3.6synchronized方法討論了定義synchronized
方法和聲明跨越整個方法體的synchronized
塊(並使用相同的對象進行同步)的相似性: 效果完全相同,但它們的表示方式不同在.class
文件中。
volatile
字段ACC_VOLATILE
產生類似的效果:它只是在字段上設置ACC_VOLATILE
標志( ACC_VOLATILE
字段 )。 訪問該字段的代碼使用相同的字節碼,但行為略有不同。
另請注意,此處僅使用volatile字段不是線程安全的 ,因為易失性字段x
上的x++
不是原子的 !
前兩個的區別就在這里:
public int getNext();
bytecodes follow...
public synchronized int getNextSync();
bytecodes follow...
至於最后一個, volatile
是變量的屬性,而不是方法或訪問該變量的JVM字節碼的屬性。 如果你查看javap
輸出的頂部,你會看到以下內容:
int last;
volatile int lastVolatile;
如果/當字節碼由JIT編譯器編譯成機器代碼時,我確信最終方法的結果機器代碼會有所不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.