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

Alex Otenko oleksandr.otenko at gmail.com
Thu Jul 6 07:52:36 EDT 2017


Thanks, Andrew. That clarifies.

Yes, CAS loop example is just for the sake of argument.

Alex

> On 6 Jul 2017, at 12:20, Andrew Haley <aph at redhat.com> wrote:
> 
> On 06/07/17 11:41, Alex Otenko wrote:
>> 
>>> 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
> 
> Something like that, yes.  But it's going to be evil if there are
> several high-frequency writers.  If you're doing all that work in
> order to CAS a timestamp, why not use a synchronized block?  It would
> at least be less prone to the thundering herd, and we'd generate
> pretty decent code for that.  It'd be interesting to compare and
> contrast the two approaches for contended and non-contended cases.
> 
>>> 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.
> 
> I agree.  I'm trying to look at what the OP actually wants to do: I
> assume this is some kind of atomic timestamp, and the OP wants to be
> able to CAS an instance of j.u.Instant.
> 
> -- 
> Andrew Haley
> Java Platform Lead Engineer
> Red Hat UK Ltd. <https://www.redhat.com <https://www.redhat.com/>>
> EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20170706/c579fe60/attachment-0001.html>


More information about the Concurrency-interest mailing list