[concurrency-interest] synchronized constructors

Ruslan Cheremin cheremin at gmail.com
Thu Dec 15 16:41:17 EST 2011


But I can pass reference between threads without any kind of
synchronization. Just assign it to shared variable in initializing
thread, and spinning while(haredRef==null){} in another, hoping on
best. This, sure, will be a data race, with all demons behind it, and
second thread can get reference to partially initialized object -- but
who will care, if constructor would be synchronized, and all
accessors/mutators too?

2011/12/16 Nathan Reynolds <nathan.reynolds at oracle.com>:
> 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 | Consulting Member of Technical Staff | 602.333.9091
> Oracle PSR Engineering | Server Technology
>
> On 12/15/2011 2:10 PM, Yuval Shavit wrote:
>
> Hi all,
>
> This came up a few days ago on 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
>
>
> _______________________________________________
> 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