Java規範的保證原始變量賦值總是原子(期待long
和雙types
。關係
相反,對應於著名i++
增值業務Fetch-and-Add操作,將非原子。因爲導致讀 - 修改 - 寫操作
假設此代碼:
public void assign(int b) {
int a = b;
}
所生成的字節碼是:
public void assign(int);
Code:
0: iload_1
1: istore_2
2: return
於是,我們看到的分配是由步驟(加載和存儲)。
假設此代碼:
public void assign(int b) {
int i = b++;
}
字節碼:
public void assign(int);
Code:
0: iload_1
1: iinc 1, 1 //extra step here regarding the previous sample
4: istore_2
5: return
明知X86處理器可以(至少現代的),原子操作遞增操作,作爲所述:
在計算機科學中,取和加CPU指令是一種特殊的指令,其原子上修改s的內存 的位置。它用於在多處理器系統中實現互斥和併發算法,這是信號量的泛化。
因此,第一個問題:儘管字節碼需要兩個步驟(加載和存儲)的事實,確實Java的依賴於一個事實,即賦值操作總是進行原子無論處理器的架構,因此操作可以確保其規範中的永久原子性(用於原始分配)?
第二個問題:這是錯誤的確認與極具現代感的X86處理器,沒有跨不同體系結構共享編譯的代碼,就沒有必要在所有同步i++
操作(或AtomicInteger
)?考慮到它已經是原子。
我的理解是,assignement的原子性只意味着istore是原子的 - 換句話說,在'a = b'中,有可能'b'被讀取,然後突變爲一個新值,然後原始值是分配給'a'。但是,原子性保證'a'不會是'b'所持有的2個值的混合。 – assylias
@assylias這就是我的想法,我同意這個觀點:) – Mik378