[concurrency-interest] synchronized constructors

Nathan Reynolds nathan.reynolds at oracle.com
Thu Dec 15 16:30:03 EST 2011


How is the MyPoint instance going to become shared with another thread?  
The thread calling the constructor has to execute some sort of 
synchronization to share the reference to the MyPoint instance.  The 
synchronization will cause a happens-before edge to be created.  For 
example, this code assigns a volatile field.  Writing to the volatile 
will ensure the proper values of x and y will be visible.

public volatile MyPoint point = new MyPoint();

Nathan Reynolds 
<http://psr.us.oracle.com/wiki/index.php/User:Nathan_Reynolds> | 
Consulting Member of Technical Staff | 602.333.9091
Oracle PSR Engineering <http://psr.us.oracle.com/> | Server Technology

On 12/15/2011 2:10 PM, Yuval Shavit wrote:
> Hi all,
>
> This came up a few days ago on stackoverflow.com 
> <http://stackoverflow.com> -- I forget the exact post, but someone 
> referenced the JLS section concerning why constructors can't be 
> synchronized:
>
>     There is no practical need for a constructor to be synchronized,
>     because it would lock the object under construction, which is
>     normally not made available to other threads until all
>     constructors for the object have completed their work.
>
>
> If synchronization were only about mutual exclusion, this would make 
> sense; but it also has memory visibility guarantees. For instance, say 
> I have this really simple class:
>
>     public class MyPoint {
>         private int x;
>         private int y;
>         public MyPoint() {
>             x = -1; // init to (-1,-1) for some reason
>             y = -1;
>         }
>
>         public synchronized void setX(int x, int y) {
>             this.x = x;
>             this.y = y;
>         }
>
>         @Override
>         public synchronized String toString() {
>             return "(" + x + ", " + y + ")";
>         }
>     }
>
> There's a thread safety issue there, right? There was no 
> synchronization during construction time, and thus no happens-before 
> between ctor ending and toString() starting, so with reordering etc, 
> you could observe the initial state as "(0, 0)", "(-1, 0)", "(-1, -1)" 
> or "(-1, 0)".  You could get around this by calling setX from the 
> constructor, but if setX is non-final, that has its own issues. You 
> could also put the x and y initialization within a synchronized (this) 
> { ... } -- but at that point, why not just allow the constructor to be 
> synchronized?
>
> Thanks,
> Yuval
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20111215/0e856b00/attachment.html>


More information about the Concurrency-interest mailing list