Question

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 two lines

newValue = new AccessStatistics(noPages, noErrors);
while (!stats.compareAndSet(prev, newValue)) 

Does it means the new created AccessStatistics instance has same reference as the current AccessStatistics instance. how could it be ? Can Anyone explain it . Thanks a lot.

Was it helpful?

Solution

stats.compareAndSet(prev, newValue) will fail and return false if the current reference held by stats is not prev.

Typically, in a multi-threaded environment, it is very possible that between prev = stats.get(); and stats.compareAndSet(prev, newValue); another thread would have modified the reference held by stats.

stats.compareAndSet(prev, newValue); really says:

  • if stats still holds a reference to prev, as it was 5 lines before, update it to hold a reference to newValue
  • if however another thread has already changed the reference held by stats since I last checked 5 lines ago, discard my calculation and loop to recalculate a new newValue.

OTHER TIPS

The newly created object is, well, new. After the line that it is created, the only thing that refers to it is newValue. Nothing else could -- how could it? The compareAndSet() only sets if nothing else has in the meantime set it to some third value, besides the old one you know about prev and the new one you made newValue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top