[concurrency-interest] DirectByteBuffers and reachabilityFence

David Holmes davidcholmes at aapt.net.au
Wed Dec 9 20:42:15 EST 2015


Justin Sampson writes:
> 
> David Holmes wrote:
> 
> > You are right about the intent here. I just found what seems to be
> > a major error in the JLS in regards to JSR-133. Here is the text
> > that was supposed to be included in the JLS update by JSR-133:
> >
> > "An object cannot be considered finalizable until all of its
> > constructors have finished. The constructor for class Object must
> > be invoked and complete normally in order for the object to be
> > finalizable; other constructors may terminate by throwing
> > exceptions."
> >
> > http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf
> >
> > But that isn't what it says in JLS 12.6.1!
> 
> As you pointed out earlier, that's just talking about whether an
> exception during construction prevents finalization. That PDF and
> the JLS both agree that an object can't be finalized at all if its
> capital-O Object constructor didn't complete normally.

You can argue that HB implies the temporal constraint even if the temporal
constraint is not explicitly part of the JLS. But the intent was that the
temporal constraint was clearly stated in the JLS. The key point being: 

"until _all_ of its constructors have finished".

That is what provides the temporal ordering - that finalize() can't start
execution until after construction is complete (normally or abnormally [as
long as Object constructor completed normally]).

If you go and read the JMM discussions from 2003/2004 you will see that the
temporal constraint is what was put in place first and then happens-before
added later to ensure the finalizer thread was guaranteed to see the
constructed object.

I don't know if Doug/Hans/Bill/Jeremy can shed any light on why the JLS was
not updated as expected, but I'd really like to know if they intended to
remove the temporal constraint, or whether they also thought the HB was
sufficient. But expecting JVM implementers to infer the need for the
temporal constraint based on one HB definition seems completely unrealistic
to me.

Cheers,
David

> The happens-before relationship is stated very explicitly, not once
> but _twice_ in the JLS. It is stated in 12.6, as I quoted earlier,
> and stated again in 17.4.5 as the second bullet point in the very
> definition of happens-before itself! It's stated even earlier than
> the fact that synchronizes-with also implies happens-before:
> 
>   "If we have two actions x and y, we write hb(x, y) to indicate
>   that x happens-before y.
> 
>   * If x and y are actions of the same thread and x comes before y
>     in program order, then hb(x, y).
> 
>   * There is a happens-before edge from the end of a constructor of
>     an object to the start of a finalizer (§12.6) for that object.
> 
>   * If an action x synchronizes-with a following action y, then we
>     also have hb(x, y).
> 
>   * If hb(x, y) and hb(y, z), then hb(x, z)."
> 
> https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-
> 17.4.5
> 
> In summary, we agree that an object can _become finalizable_ before
> completion of its constructor, if the Object constructor completed
> normally and the object is otherwise no longer reachable. But the
> definition of happens-before makes it very clear that whenever the
> finalizer _does_ run, it will see all writes from the remainder of
> the constructor and none of its writes will be visible within the
> constructor.
> 
> Cheers,
> Justin
> 
> _______________________________________________
> 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