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.
stats.compareAndSet(prev, newValue)will fail and return false if the current reference held bystatsis notprev.Typically, in a multi-threaded environment, it is very possible that between
prev = stats.get();andstats.compareAndSet(prev, newValue);another thread would have modified the reference held bystats.stats.compareAndSet(prev, newValue);really says:statsstill holds a reference toprev, as it was 5 lines before, update it to hold a reference tonewValuestatssince I last checked 5 lines ago, discard my calculation and loop to recalculate a newnewValue.