[concurrency-interest] Should I avoid compareAndSet with value-based classes?
oleksandr.otenko at gmail.com
Thu Jul 6 06:41:43 EDT 2017
> On 6 Jul 2017, at 10:13, Andrew Haley <aph at redhat.com> wrote:
> On 06/07/17 04:59, Michael Hixson wrote:
>> AtomicReference and VarHandle are specified to use == in compareAndSet
>> (and related) operations . Using == to compare instances of
>> value-based classes may lead to "unpredictable results" . Does
>> this mean I should avoid using compareAndSet with arguments that are
>> instances of value-based classes?
>> It seems like the documentation clearly tells me "yes, avoid doing
>> that" but I'm hoping I misunderstood, or maybe AtomicReference and
>> VarHandle are exempt somehow. Otherwise, how do I implement
>> non-broken compareAndSet and updateAndGet for a java.time.Instant
>> value for example?
> java.time.Instant stores times that are longer than a JVM word, so
> they cannot be CAS'd in a lock-free way unless a factory guarantees
> that instances which compare equal also have the property of
> reference equality. j.t.Instant factories in the Java library are
> explicitly documented *not* to have this property, so that doesn't
That’s not entirely clear.
Wouldn’t this loop work:
volatile j.t.Instant curr = ...
j.t.Instant next = …
j.t.Instant tmp = ...
tmp = curr;
if (tmp.equal(next)) break;
} while(!curr.CAS(tmp, next));
// assume curr is equal to next
> If you want to be able to CAS a reference to a j.t.Instant, you're
> going to have to wrap accesses to it in a synchronized block. This is
> a direct consequence of the JVM's inability to CAS multi-word objects.
This is confusing.
Surely this isn’t talking about CASing a reference? The contents of the object can’t be assumed to have any atomicity properties, whether it is j.t.Instant or not.
> There are some things we know, however, despite the documentation of
> "Value-based Classes". For any reference r, r == r. If r refers to a
> value-based class, r.equals(r) will always return true. I don't think
> that anything which appears in that section can overrule these basic
> properties. Because of this, you can keep a pool of Instant
> instances and intern them, and then, I believe, a reference CAS will
> work. But you'll need a synchronized factory to do that.
> Obviously a CAS-able timestamp would be a nice thing to have, but
> java.time.Instant is not the timestamp you're looking for.
> Andrew Haley
> Java Platform Lead Engineer
> Red Hat UK Ltd. <https://www.redhat.com>
> EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
More information about the Concurrency-interest