2009-12-08 74 views
3

假設你有下面的類AtomicReference.compareAndSet()用於確定什麼?

public class AccessStatistics { 
    private final int noPages, noErrors; 
    public AccessStatistics(int noPages, int noErrors) { 
    this.noPages = noPages; 
    this.noErrors = noErrors; 
    } 
    public int getNoPages() { return noPages; } 
    public int getNoErrors() { return noErrors; } 
} 

,你執行下面的代碼

private AtomicReference<AccessStatistics> stats = 
    new AtomicReference<AccessStatistics>(new AccessStatistics(0, 0)); 

public void incrementPageCount(boolean wasError) { 
    AccessStatistics prev, newValue; 
    do { 
    prev = stats.get(); 
    int noPages = prev.getNoPages() + 1; 
    int noErrors = prev.getNoErrors; 
    if (wasError) { 
     noErrors++; 
    } 
    newValue = new AccessStatistics(noPages, noErrors); 
    } while (!stats.compareAndSet(prev, newValue)); 
} 

在最後一行while (!stats.compareAndSet(prev, newValue))怎樣的compareAndSet方法確定prevnewValue之間的平等?執行equals()方法需要AccessStatistics類嗎?如果不是,爲什麼?的Javadoc國AtomicReference.compareAndSet

以下原子方式將該值設置爲給定的更新值,如果當前值==預期值。

......但是這個斷言看起來非常普遍,我在AtomicReference上讀過的教程從來沒有建議對包裝在AtomicReference中的類實現equals()。

如果在AtomicReference中包裝的類需要實現equals(),那麼對於比AccessStatistics更復雜的對象,我認爲同步更新對象並且不使用AtomicReference的方法可能會更快。

+1

「但這種說法似乎很一般」......相反,它是非常具體的。在Java中,「==」表示'=='運算符。 – 2009-12-09 04:56:14

+1

我能說什麼?我的強迫症迫使我看到它在幾個方面說。如果可以的話,我也會投票贊成尤金的回答。 – Rapier 2009-12-09 18:02:28

回答

4

它比較refrerences就像你使用==運算符一樣。這意味着引用必須指向相同的實例。沒有使用Object.equals()。

0

它只是檢查對象引用的相等性(aka ==),所以如果AtomicReference保存的對象引用在獲得引用後發生了變化,它將不會更改引用,因此您必須重新開始。

2

其實,它確實不是比較prev和newValue!

相反,它將統計數據中存儲的值與prev進行比較,只有當這些值相同時,纔會將統計數據中存儲的值更新爲newValue。如上所述,它使用等號運算符(==)來執行此操作。這意味着,當prev指向與存儲在統計數據中相同的對象時,就會更新統計數據。