[concurrency-interest] Should I avoid compareAndSet with value-based classes?

Alex Otenko 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 [1].  Using == to compare instances of
>> value-based classes may lead to "unpredictable results" [2].  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
> help.

That’s not entirely clear.

Wouldn’t this loop work:

volatile j.t.Instant curr = ...

j.t.Instant next = …
j.t.Instant tmp = ...
do {
  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.


Alex


> 
> 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
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest



More information about the Concurrency-interest mailing list