5

Java's AtomicInteger offers public final boolean compareAndSet(int expect, int update). If false is returned, I would like to know what the value actually was at the time when the comparison failed. Is this possible in Java?

In .Net, there's public static int CompareExchange(ref int location1, int value, int comparand), which always returns the original value.

Evgeniy Berezovsky
  • 18,571
  • 13
  • 82
  • 156

2 Answers2

2
public int getAndCompareAndSet(AtomicInteger ai, int expected, int update) {
  while (true) {
    int old = ai.get();
    if (old != expected) {
      return old;
    } else if (ai.compareAndSet(old, update)) {
      return old;
    }
  }
}

(This sort of loop is how most operations on AtomicInteger are implemented: loops of get, do some logic, try compare-and-set.)

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • 1
    I wonder if that's what .Net does internally as well, or if .Net can do all that atomically in one go, which would seem to be faster. Not sure if some such operation exists on the machine level. – Evgeniy Berezovsky Nov 13 '15 at 01:40
  • 1
    x86 has a single instruction for this: http://x86.renejeschke.de/html/file_module_x86_id_41.html – Matt Timmermans Nov 13 '15 at 01:47
  • (Please ignore -> )That's not really atomic, though. Between `ai.get()` and `ai.compareAndSet()`, the stored value may have been changed by another thread. – vanza Nov 13 '15 at 02:31
  • @vanza, of course it may be. That's why we only return if `compareAndSet` returns `true`, in which case `ai` didn't change in between. This is exactly what e.g. `AtomicInteger.getAndAdd` does. – Louis Wasserman Nov 13 '15 at 02:32
  • My bad, I missed the loop. – vanza Nov 13 '15 at 02:32
0

The API does not expose such a method. What's more, the Oracle implementation uses sun.misc.Unsafe to do the native CAS operation and that type doesn't expose it either.

One option is to just call get() if compareAndSet returned false. However, by the time you check it, the actual value of the AtomicInteger might have changed. There's not much you can do with it. This is true for Interlocked methods as well. You'd have to clarify what you want to do with that value to go any further.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724