Your modification to use hashCode won't work either. The reasoning I put
forward before still applies:
> In practice, with your solution, you could easily imagine a compiler
> with a perfect understanding of getClass(); it reasons:
> a) instance is initialized when getClass() is called, therefore
> b) "instance.getClass() != null" will always be true, and,
> b.5) there are no other side effects to this call, and thus
> c) you can replace the statement with "initialized = true", and
> d) you can move the statement to before the constructor for
> initialized is called, but after the assignment to instance (which
> has already been moved early as per the usual explanation).
> Then the reader can see initialized == true and instance != null, and
> not see the correctly constructed values of the instance.
This optimization works with any solution of this form. We just replace
"perfect understanding of getClass()" with "perfect understanding of
hashCode()". Anything that you can figure out that will /guarantee/ that
true is written to initialized can be deduced by the compiler, after which
the write to initialized can be moved early. True, in the case of
hashCode() it may be a little harder (depending on how the method is
implemented), but it will still be possible.
Again (and I think this is worth pounding on, so I will), you cannot
guarantee writes will be communicated between threads without an explicit
ordering / synchronization relationship. Locks, unlocks, volatiles, class
intialization and so on.
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:51 EDT