[concurrency-interest] AtomicReference.updateAndGet() mandatory updating
oleksandr.otenko at gmail.com
Sat May 27 18:36:52 EDT 2017
> On 27 May 2017, at 18:13, Justin Sampson <jsampson at guidewire.com> wrote:
> Alex Otenko wrote:
>> If whoever mutated z from i to k cannot observe stores that precede z.CAS,
>> they won’t attempt to mutate z to j.
> In your example, how does that other thread know that it is responsible for mutating z to j? What if it has gone on to other things before z.CAS(i, j) even happens?
That’s not a hard problem. Extra flag can deal with that, but most of the time you only check its value.
>> In return can someone explain what the difference is between a
>> weakCompareAndSet failing spuriously and compareAndSet not guaranteeing
>> volatile store semantics on fail? Why should we weaken the promise, if there
>> is already a weak promise to not guarantee visibility on fail?
> Spurious failure is more about the read than the write, I think. With spurious failure, you can't even rely on volatile read semantics if the CAS fails, because failure doesn't give any information at all about the current value. Without spurious failure, at the very least you know that the current value != the expected value if the CAS fails.
No, that’s not spurious enough failure.
Spurious failure can mean CAS failed because the cache line from which the value was read got invalidated (available on some weak memory platforms). So you can’t tell even whether the value was != expected or not, or whether someone modified a different value that happens to share the cache line - hence spurious.
In this setting it does not seem possible to detect whether the read was volatile or not.
> Consider the following levels of CAS strength, off the top of my head:
> 1. Volatile read always, volatile write always, no spurious failures.
> 2. Volatile read always, volatile write only if successful, no spurious failures.
> 3. Volatile read always, volatile write only if value changed, no spurious failures.
> 4. Volatile read only if successful, volatile write only if value changed, spurious failures allowed.
> 5. No volatile read, no volatile write, spurious failures allowed.
> In JDK 8, compareAndSet was spec'd as #1 and weakCompareAndSet was spec'd as #5, whereas e.g. AtomicStampedReference's compareAndSet method was actually implemented as #3. In my limited concurrency coding, I don't think I've ever wanted something stronger than #3 or weaker than #4. I will be curious to learn whether any of the CAS versions in JDK 9 match those two particular levels.
More information about the Concurrency-interest