[concurrency-interest] synchronized on construction

Jeremy Manson jmanson at cs.purdue.edu
Wed May 24 10:10:21 EDT 2006


Thomas Hawtin wrote:
> Under the new JMM would a synchronised block in the constructor 
> guarantee to fix the problem? Does the racy write of the Vector 
> reference, outside of the synchronised block, necessarily come after the 
> block itself. Could it technically be moved up before the lock is 
> acquired? Or am I misinterpreting something?
> 

The system will not move the racy write up before the lock is acquired, 
although it may move it inside the synchronization block.  We have 
"Roach Motel Semantics" - you can move the write up into the 
synchronization block, but you can't move it out of that block.

The reason for this has to do with locking and happens-before, and I 
shall leave it as an exercise to the reader ;) .

I want to reiterate my previous statement.  If you are using this class, 
you have to use synchronization to ensure that the reference to the 
object gets communicated between threads *at all*.  As long as you are 
doing this, the happens-before relationship will be present, so you are 
safe.

If you don't have that synchronization in your code, then there you have 
a bug.  A data race.  Data races rot the brain and corrupt the soul.

> Bug 6379897 deals with the thread safety of Random's seed when 
> constructed lazily in Collections. It's interested to see that the fix 
> for that attempts to make the use of seed thread-safe, rather than 
> construct the Random safely in Collections. Presumably the details of 
> that fix (setting of the seed value) require that my first paragraph is 
> wrong...
> 
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6379897

This bug discusses making the seed final, which ends up being a separate 
issue from the one in your first paragraph.  Declaring a field final 
means that the correctly constructed value will be visible to threads 
that see a reference to that object, even if you have no additional 
synchronization.  It is an excellent way to provide thread-safe 
initialization, as long as your field doesn't change.  This cannot be 
done for the fields of Vector, though, because its fields can be changed.

The final modifier is a good one in general, and, like "private", should 
be used wherever possible.  A caution: final field guarantees are only 
made to threads that do not see, via a data race, a reference to the 
object that was written in the constructor.

The bug has this comment:

> The submitter is correct (according to the Java Memory Model).
> However, we can't seem to make these bugs actually manifest in the wild.
> We would love an actual test on the Sun JDK that demonstrates the failure
> (even if only once in a million tries).

Maybe it doesn't happen on their testbed, but wait until someone makes 
that one tweak to the VM and tries to run the code on 384 processors...

					Jeremy


More information about the Concurrency-interest mailing list