我在多執行緒應用程式中有一個類:
public class A {
private volatile int value = 0; // is volatile needed here?
synchronized public void increment() {
value ; // Atomic is better, agree
}
public int getValue() { // synchronized needed ?
return value;
}
}
uj5u.com熱心網友回復:
關鍵字volatile為您提供可見性方面,否則您可能會讀取一些陳舊的值。易失性讀取增加了記憶體屏障,使得編譯器、硬體或 JVM 無法以違反記憶體模型提供的可見性保證的方式重新排序記憶體操作。根據記憶體模型,對 volatile 欄位的寫入發生在每次后續讀取同一欄位之前,因此您可以保證讀取最新值。
synchronized由于您正在執行value 必須以原子方式完成的復合操作,因此還需要關鍵字。您讀取該值,在 CPU 中將其遞增,然后將其寫回。所有這些操作都必須以原子方式完成。但是,您不需要synchronize讀取路徑,因為關鍵字volatile保證了可見性。事實上,在讀取路徑上同時使用volatile和synchronize會令人困惑,并且不會提供任何性能或安全優勢。
通常鼓勵使用原子變數,因為它們使用 CPU 中內置的 CAS 指令使用非阻塞同步,從而產生低鎖爭用和更高的吞吐量。如果它是使用原子變數撰寫的,它將是這樣的。
public class A {
private final LongAdder value = new LongAdder();
public void increment() {
value.add(1);
}
public int getValue() {
return value.intValue();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/359318.html
下一篇:掛起和恢復執行緒的問題
