[concurrency-interest] synchronized constructors

Vitaly Davidovich vitalyd at gmail.com
Thu Dec 15 19:13:35 EST 2011


I think in practice having at least one final field assignment in the
constructor, irrespective of order, will cause the storestore to be emitted
after the constructor and before publishing assignment (at least in
hotspot,  to my knowledge).  Relying on this though is probably not
prudent.  If you realize that a constructor is just a method (albeit
special) which can get inlined then you can see how operations can be
reordered because placement of final field assignment is more obvious
(people tend to think of constructors as some "atomic" block of code, which
isn't right IMHO).

However, I find it hard to believe that even though this behavior is
implementation specific that Oracle would change this such that order of
final field assignment matters - this could break massive amounts of code,
especially as we're getting more and more concurrency in commodity hardware.

Outside of a purely "academic" discussion here, the main point is avoid
data racy code :).
On Dec 15, 2011 6:54 PM, "Yuval Shavit" <yshavit at akiban.com> wrote:

> From my cursory reading of the JLS and the cookbook that David linked to,
> I think you're right. The JMM would allow such a reordering, but it sounds
> like you'd need to actively work on it if you wanted the compiler to honor
> final field semantics but allow the reordering that would result in the 0
> being seen.
>
> What if you just had a final field that you wrote but didn't use?
>
>     final int a;
>     int b;
>
>     MyConstructor() {
>         a = 1;
>         b = 2;
>     }
>
> I believe this was the original suggestion to replace the
> synchronized(this) in the ctor (Natha's email that starts, "One could also
> add a final field in the class..."). Would that more readily exploit seeing
> b == 0? And would it be different if the assignments had happened in
> reverse order (b = 2; a = 1) ?
>
> On Thu, Dec 15, 2011 at 6:20 PM, Vitaly Davidovich <vitalyd at gmail.com>wrote:
>
>> I think I misinterpreted the question.  Yes if you publish in the middle
>> of construction then anything goes - final won't help.  If the question is
>> about unsafe publication after the constructor, then I think in practice it
>> works because the compiler will issue one storestore after the constructor
>> and before publishing (regardless of order of final field store in the
>> constructor ).  In that case, if another thread reads a non-null instance
>> it should see all writes done inside the constructor.  Presumably though, a
>> compiler could only issue a storestore after the final field, move the
>> publishing assignment ahead of the non-final field write, and then a
>> non-null read on the other thread doesn't guarantee anything about the
>> non-final field.  I don't think JMM precludes this scenario.
>>
>> Sorry for the dense text I'm on my phone :).
>> On Dec 15, 2011 5:53 PM, <dhanji at gmail.com> wrote:
>>
>>> From a cursory glance, it could happen if the b's value (=a) is sitting
>>> in a cache line in the CPU for instance. I don't think there is any
>>> guarantee that b is published correctly. The semantics depend on the
>>> publication of the container object and participating threads.
>>>
>>> I've seen similar things happen in the 64-bit JVM.
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20111215/49dead5a/attachment.html>


More information about the Concurrency-interest mailing list