Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does AtomicReference.compareAndSet() use for determination?

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.

like image 874
Rapier Avatar asked Dec 08 '09 21:12

Rapier


People also ask

How does AtomicReference work?

AtomicReference refers to an object reference. This reference is a volatile member variable in the AtomicReference instance as below. private volatile V value; get() simply returns the latest value of the variable (as volatiles do in a "happens before" manner).

Why use AtomicReference?

An atomic reference is ideal to use when you need to share and change the state of an immutable object between multiple threads. That is a super dense statement, so I will break it down a bit. First, an immutable object is an object that is effectively not changed after construction.

What is an AtomicReference in Java?

AtomicReference class provides operations on underlying object reference that can be read and written atomically, and also contains advanced atomic operations. AtomicReference supports atomic operations on underlying object reference variable.

What is compareAndSet?

compareAndSet() is an inbuilt method in java that sets the value to the passed value in the parameter if the current value is equal to the expected value which is also passed in the parameter. The function returns a boolean value which gives us an idea if the update was done or not.


2 Answers

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.

like image 154
Mike Daniels Avatar answered Oct 20 '22 18:10

Mike Daniels


Actually, it does not compare prev and newValue!

Instead it compares the value stored within stats to prev and only when those are the same, it updates the value stored within stats to newValue. As said above it uses the equals operator (==) to do so. This means that anly when prev is pointing to the same object as is stored in stats will stats be updated.

like image 25
Stijn de Witt Avatar answered Oct 20 '22 16:10

Stijn de Witt