2009-12-08 56 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指向与存储在统计数据中相同的对象时,就会更新统计数据。