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

Gil Tene gil at azul.com
Sat Jul 8 08:22:33 EDT 2017

> On Jul 8, 2017, at 1:19 AM, Andrew Haley <aph at redhat.com> wrote:
> On 08/07/17 07:38, Gil Tene wrote:
>> My arguments here are not about trying to justify some compiler
>> optimizations, or trying to justify the choices of making these
>> things subclasses the Object. They are about pointing out the actual
>> meaning of things as defined and the (very high risk) of coding
>> against it based on a hope that some temporarily observed behavior
>> is actually reliable, when everything that describes what it does
>> says otherwise.
> I disagree with this interpretation.  You're interpreting the language
> in that paragraph as overriding some fundamental properties in the JLS.

To keep this to a simple case that

What specific property of the JLS requires that == not be always-false?

I.e., what is it in the JLS that requires that this loop ever terminate when there is no external interference by another thread?:

  // David Lloyd's example from earlier in the thread (Jul 6, 10:48AM PDT):
  AtomicReference<Instant> atomic;
  Instant a, b;
  do {
      a = atomic.get();
      b = compute(a);
  } while (! atomic.compareAndSet(a, b));

or for that matter, that this loop ever terminate when there is no external interference by another thread?:

  volatile Instant thing;
  Instant a, b;
  boolean success = false;
  do {
      a = thing;
      b = compute(a);
      if (thing == a) {
          thing = b;
          success = true;      
  } while (!success);

The termination of both of these loops relies on the notion of identity (the logical value of a reference) being preserved between the reading of a reference to an instance of a value-based class from memory, and the eventual comparison of that instance's reference with another one stored in a memory location.

I'm really asking… I'd love to find something in the JLS that says this must be preserved, and thereby contradict the statements that say that instances of value-based classes "are freely substitutable when equal" and "Use of such identity-sensitive operations on instances of value-based classes may have unpredictable effects". 

I'd like to point out that Instant happens to be one of those cool ""partially compressible value" classes who's value cannot be fully represented with a single 64 bit value, but where "a wide and interesting range" of values can be: specifically, all the possible values of Instant between the epoch and some time in the year 2043 *can* be represented in 63 bits, making smalltalk-like inlined "it's not a pointer, it's a value" representations very possible (e.g. negative references are actual the values) and appealing for many reasons (both space and speed). This works as long as both identity and type can be erased from the contents without hurting computations [which can be done safely when stored in registers whose type is known, for example]. And this quality is specifically provided by the documentation of the type as a value-based class.

However, since it is possible for instances of Instant to be stored in locations that do not have this quality [e.g. Object fields, or even known-to-be-of-type-Instant fields in memory depending on implementation], each possible "compressible value" also needs a non-compressed representation in a heap-based object contents form. This means that the value in the memory location may be a true reference, while the value we read into local variables may not be, at least for a wide range of possible values. And that in turn means that the loops above will never terminate (since they will never be able to show that the reference contents of "atomic" or of "thing" is == to the value in a).

> In the case of C, the thing to do would be to ask for a clarification,
> but I suspect that if we asked, say, John Rose, Alex Buckley, and
> Brian Goetz we'd get different answers.  ;-)
> -- 
> Andrew Haley
> Java Platform Lead Engineer
> Red Hat UK Ltd. <https://www.redhat.com>
> EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671

More information about the Concurrency-interest mailing list