[concurrency-interest] Question about "happens-before" and reordering

Jeremy Manson jmanson at cs.purdue.edu
Fri May 19 11:51:35 EDT 2006


Robert Kuhar wrote:
> I asserted that they had two problems with this code.  As I understand it, the
> runtime is free to reorder the instructions in this constructor.  This means
> that initialized=true may occur before the calls to either securityCheck() or
> init().  If that is the case, its value cannot be trusted as this code stands
> now.

This is not the case.  In Java, exceptions are precise, and must be 
treated like control flow.  The write will only occur if the exception 
is not thrown.  Neither this thread nor any other can see a write that 
does not occur.  This is one of those very few, tricky to get, 
guarantees for programs with data races that we make.

So, the point that the speaker was probably trying to make, which is 
that you can check the value of "initialized" to determine if 
securityCheck() exited without throwing an exception, is perfectly valid.

The compiler is free to move the write to initialized early if it can 
determine that the exception will not be thrown.  It is also free to 
hoist it above the call to init() (depending on what init() actually 
does).  This means that if another thread can obtain a reference to this 
object via a data race, and reads the "initialized" variable, it can see 
the value "true" even if the object is not fully constructed. 
Alternatively, such a thread could see a value "false" for initialized 
even if the object is fully constructed.

A few things to note:

0) Why isn't this class final?

1) As has been noted, constructors are guaranteed to happen-before 
finalize methods.  Therefore, finalizers will see all the writes that 
occur in the constructor.  For the purposes of whether this code does 
what it is intended to do, though, this is irrelevant, because the 
finalizer (I assume) is just resurrecting the object.

2) The initialized field should probably be final (which would mean that 
you could not put the "initialized = false" line in, but you probably 
don't want that line there anyway, as the default value is false, and 
moving the constructor around / adding more constructors will cause 
confusion).  Otherwise, you could use reflection to set it.

					Jeremy



More information about the Concurrency-interest mailing list