0

I got some questions about AtomicReference.compareAndSet() method, according to the doc, it said:

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

As far as I understand, the == operator is comparing the address of two objects, if so how will it work in examples like this

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 this code snippet, how does jvm know which fields of AccessStatistics are to be compared in the compareAndSet()? In fact I'm just wondering how is this whole strategy working given java doesn't allow to override == at all? Thanks for any comments!

Gray
  • 115,027
  • 24
  • 293
  • 354
Arrow Cen
  • 733
  • 1
  • 8
  • 22
  • Here is a very similar question, even with the same example: http://stackoverflow.com/questions/1869959/what-does-atomicreference-compareandset-use-for-determination?rq=1 – Philipp Wendler Jul 27 '12 at 16:27

2 Answers2

5

how does jvm know which fields of AccessStatistics are to be compared in the compareAndSet()?

It doesn't. It is not comparing the fields in the object. It is just comparing the reference of the object which is what the documentation says. That's just how the AtomicReference class works. As you mention from the javadocs, it uses == and not the equals() method.

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

All of the Atomic* classes have similar functions. It allows you to atomically set values while being sure that another thread doesn't overwrite your value. With compareAndSet(...) you have to specify the current object reference to ensure you are updating as expected.

In your code snippet, it is trying to add to an immutable access-statistics object. So it gets the current value, adds to it, and then stores the new statistic to the reference. If another thread stored its stats between that time, then the compareAndSet will return false and it loops around and tries again. This solves race conditions without having to have a synchronized block.

Gray
  • 115,027
  • 24
  • 293
  • 354
  • Thanks Gray, that being said, AtomicReference is only used for IMMUTABLE object, this makes things much clearer to me. I would assume how this is going to work if we just modify some fields inside prev... But in this case it's just Overriding the value of stats, and that would resulting the stats object pointing to another object, and == will work. – Arrow Cen Jul 27 '12 at 17:17
  • @ArrowCen Well there's nothing that requires immutability but yes, as I mention in my answer, your code snippet is dealing with what looks like an immutable object. FYI: `==` will also work with mutable objects. – Gray Jul 27 '12 at 17:20
2

The JVM doesn't compare the fields at all. It just compares whether or not it's the same reference, the same pointer in memory, or whatever you want to call it.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413