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

Alex Otenko oleksandr.otenko at gmail.com
Mon Jul 10 06:02:59 EDT 2017

Thanks, this is very useful.

What about

Runnable r1 = () -> {};
Runnable r2 = r1;
assert r1 == r2;

should we expect a bombshell here? Clearly, autoboxing/unboxing is allowed to happen, if, say, r1 and r2 were Integers, but which side of the surprising behaviour will the JVM choose?


> On 10 Jul 2017, at 10:53, Aleksey Shipilev <shade at redhat.com> wrote:
> On 07/10/2017 11:22 AM, Andrew Haley wrote:
>> Indeed.  I already quoted the language in the JLS I'm relying on, and
>> said that I find it convincing.  I believe that 15.21.3, "Reference
>> Equality Operators == and !=" would have to be changed in order for
>> your interpretation of reference equality to be correct.
>> So let's move on to another matter, the JVM specification, and the way
>> that Java maps on to the JVM.  In the JVM, the instruction if_acmpeq
>> is supposed to return true if value1 = value2.  So,
>>   dup; if_acmpeq
>> is bound to succeed.
>> You could argue that it is theoretically possible that Java could be
>> compiled onto the JVM in some other way, so that your interpretation
>> of the JLS would be correct, but I don't think it's much to worry
>> about.  You could also argue that the section which describes
>> value-based classes implicitly changes the JVM specification, but I'd
>> like to see that in writing.
> I remember this was the early confusion with lambdas, which had the relaxed
> notion of identity too. And there was the same confusion of "OMG, I can get the
> exception doing '==' on lambda?!". But that only extended to "you don't know
> what would the evaluation result of lambda expression be: it might be equal to
> something else, or not".
> That is:
>  Runnable r1 = () -> {};
>  Runnable r2 = () -> {};
>  assert (r1 == r2);                       // deliberately unspecified
>  assert (r1.getClass() == r2.getClass()); // deliberately unspecified
>  assert (r1 == r1);                       // keeps being true!
>  assert (r2 == r2);                       // keeps being true!
>  assert (r1.getClass() == r1.getClass()); // keeps being true!
>  assert (r2.getClass() == r2.getClass()); // keeps being true!
> I think that for value objects, whether they are really implemented on JVM, or
> they are just declared in Javadoc, the same thing applies. This stance in docs
> is the key: "[Value-based classes:] - do not have accessible constructors, but
> are instead instantiated through factory methods which make no committment as to
> the identity of returned instances;". The rest of the properties seem to be
> derived from that unreliable identity.
> In other words, "no commitment" reads as "identity is unknown" rather than
> "identity is non-existent". Unknown identity is still reflexive, symmetric,
> transitive. The identity of the value type *box* that you get from the
> expression should be deliberately unspecified to provide implementation freedom,
> but once you get the boxed reference, it is bound by the same JLS rules Andrew
> quotes.
> In yet other words, "value-based class" tells to be careful about the identity
> semantics of producing expressions, but it does not relax the semantics of the
> boxed references you get from them either explicitly or implicitly. This is
> pretty much like current primitive autoboxing works :)
> Thanks,
> -Aleksey
> _______________________________________________
> 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