它是安全的假設,(AtomicInteger a).addAndGet(-1)
之前的代碼將在調用之前一直執行的,即JVM將不重新排序圍繞addAndGet
調用的指令?是JVM允許指令重新排序,周圍的AtomicInteger調用
如果是的話,是可以安全地假設其他線程檢查同一AtomicInteger
實例的狀態(例如if (a.compareAndSet(0, -1))
)將看到的一切addAndGet
調用之前的第一個線程發生了變化?
它是安全的假設,(AtomicInteger a).addAndGet(-1)
之前的代碼將在調用之前一直執行的,即JVM將不重新排序圍繞addAndGet
調用的指令?是JVM允許指令重新排序,周圍的AtomicInteger調用
如果是的話,是可以安全地假設其他線程檢查同一AtomicInteger
實例的狀態(例如if (a.compareAndSet(0, -1))
)將看到的一切addAndGet
調用之前的第一個線程發生了變化?
它是安全的假設,之前的代碼(的AtomicInteger 一).addAndGet(-1)將總是此調用之前執行,即JVM 不會重新排序圍繞addAndGet調用的指令?
是的,這是正確的。 addAndGet
將發出一個易變的商店(或類似的),因此其他加載和存儲不能在其下面重新排序。
編輯:謝謝Soitrios鏈接https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html,這表明有一個建立秩序爲你。
- 獲得讀取volatile變量的內存效果。
- 集具有寫入(分配)易失性變量的內存效果。
- compareAndSet和所有其他讀取和更新操作(如getAndIncrement)都具有讀取和寫入易失性變量的內存效果。
不僅JVM被阻止,CPU也被阻止了。即CPU也可以重新排序指令的執行。 –
@John Vint,你是否同意上面關於「if(a.compareAndSet(...))」內部的@Holger註釋,你只能保證看到線程所做的更改,期望值」? – Gedrox
是的,我同意這種說法。由於我們不能說失敗的線程成功寫入,它永遠不會發出易失性存儲。因此,該線程的寫入和連續線程的讀取之間沒有同步。 –
我相信你只能依賴set發生的事實 - 在得到特定的AtomicInteger之前。 –
要挑剔,你從來沒有任何關於何時被執行的保證,而是關於*可觀察到的效果*。但是這實際上是你感興趣的。你不應該忽略'if(a.compareAndSet(...))'中的內容,你只能保證看到線程所做的改變,值。所以你必須確保沒有多種方法來達到這個價值...... – Holger
@Holger,在這種情況下可能會有什麼幫助?我必須看到所有線程的變化減少了'a'的值,最後一個使其爲零的線程必須與從所有線程收集的數據一起工作。 – Gedrox