views:

215

answers:

2

Say you have the following class

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; }
}

and you execute the following code

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));
}

In the last line while (!stats.compareAndSet(prev, newValue)) how does the compareAndSet method determine equality between prev and newValue? Is the AccessStatistics class required to implement an equals() method? If not, why? The javadoc states the following for AtomicReference.compareAndSet

Atomically sets the value to the given updated value if the current value == the expected value.

... but this assertion seems very general and the tutorials i've read on AtomicReference never suggest implementing an equals() for a class wrapped in an AtomicReference.

If classes wrapped in AtomicReference are required to implement equals() then for objects more complex than AccessStatistics I'm thinking it may be faster to synchronize methods that update the object and not use AtomicReference.

A: 

It simply checks the object reference equality (aka ==), so if object reference held by AtomicReference had changed after you got the reference, it won't change the reference, so you'll have to start over.

Eugene Kuleshov
+1  A: 

It compares the refrerences exactly as if you had used the == operator. That means that the references must be pointing to the same instance. Object.equals() is not used.

Mike Daniels