[英]Inconsistent State Comparison Java
在Java Concurrency In Practice中 ,給出了一個示例*來演示可見性問題,其中兩個不同的線程由於缺少同步而可能看不到任何特定可變對象的最新狀態。
public class Holder {
private int n;
public Holder(int n) { this.n = n; }
public void assertSanity() {
if (n != n){
throw new AssertionError("This statement is false.");
}
}
在此特定示例中,該書指出應首先初始化線程“ A”並通過線程不安全的方式發布它,例如:
public Holder holder;
public void initialize() {
holder = new Holder(42);
}
然后,線程“ B”調用holder.assertSanity()
,由於狀態不一致,很有可能引發AssertionError
。
現在,我了解了該參數的基本前提,即對可變變量所做的更改可能永遠不會被另一個線程觀察到。 但是我在這里感到困惑的是,它正在比較相同的(或我認為)參考n != n
。
這不比較可變基本字段private int n
嗎? 不管現在線程A的n
值可以為42,線程B的n
值可以為0(默認值),無論是否直接調用以檢查同一線程中的值是否一致 ? 即在線程A中調用assertSanity()
將檢查是否42 != 42
,在線程B中是否為0 != 0
?
*參考3.5安全出版物中的清單3.14和3.15。
問題在於,在表達式n != n
,變量n
將被加載兩次(假設未對字節碼進行優化)。 在這兩個負載之間,另一個線程可以更改該值。
在線程B中比較n != n
,B檢索n
兩次。 同時,在線程A中運行的構造函數會將n的值從默認0修改為42。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.