JavaMemoryModel: Rules on objects escaping their constructor

From: Bill Pugh (pugh@cs.umd.edu)
Date: Thu Sep 14 2000 - 11:37:06 EDT


I didn't see much in the way of objections to my earlier proposal
about object visible and constructors, so it looks like people are
happy with this. I will be very happy with it, because it will
greatly simply the semantics and keep me from bashing my head against
the wall trying to get the complicated version right.

Let me go over it one more time, just to make sure everyone is happy with it.

A constructor should not allow an object to be reachable from any
other thread until after the constructor has terminated. This rule
will not be checked or enforced. But when it is violated, final
fields of the object will have unpleasant semantics (i.e., they will
be treated as pseudo-final fields).

It is irrelevant that synchronization or other mechanisms are used to
guarantee that no other threads reads the reference until after the
constructor terminates. The key issue is whether it is reachable;
storing a reference to the object into a static field or any data
structure reachable from a static field makes it reachable by other
threads.

Rational: In addition to making things work well for final fields,
this is a good programming practice to follow in general. In fact,
you should probably follow a stricter rule: that when a constructor
returns, the object constructed is only reachable through the value
returned by the constructor. If this practice is violated, then you
cannot safely extend the class; if an exception occurs in a
higher-level constructor, the object is still captured.

Although this strong rule might be good practice, I don't believe
there is any need to incorporate it into the semantics of final.

The implementation of final would be:

* You may not reorder any write done before a constructor terminates and
        any write, following the constructor, that may make the object
        reachable from other threads

* You may not reorder a read of a reference to an object, and a read of
          a final field of that object nor any value reached from the final
        field (e.g., if the final field of a String is a reference to an array
        of characters, you may not reorder the read of the reference to
        the string and the read of a character of the array).
   * reads of final fields can be moved across memory barriers

The first item would impose minor constraints on compiler
optimization, and a memory barrier on systems that can reorder
writers. The second item should have no impact on compiler
optimizations, and require a memory barrier only on systems with a
memory model weaker than RMO (i.e., ones that can reorder dependent
reads), such as an Alpha.

        Bill
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:27 EDT