river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Firmstone <j...@zeus.net.au>
Subject Re: code comment in TxnManagerImpl
Date Mon, 01 Apr 2013 20:10:35 GMT
Concurrency is a complex subject even experts struggle with, I know 
you're a good programmer, I think the discussion will be more fruitful 
here, to be honest, I'm just following coding rules that much smarter 
developers have devised for me:

Send Concurrency-interest mailing list submissions to
	concurrency-interest@cs.oswego.edu

To subscribe or unsubscribe via the World Wide Web, visit
	http://cs.oswego.edu/mailman/listinfo/concurrency-interest
or, via email, send a message with subject or body 'help' to
	concurrency-interest-request@cs.oswego.edu

You can reach the person managing the list at
	concurrency-interest-owner@cs.oswego.edu


Cheers,

Peter.

Dan Creswell wrote:
> Dude,
>
>
> On 1 April 2013 12:10, Peter Firmstone <jini@zeus.net.au> wrote:
>
>   
>> Hmm, :|
>>
>> To quote http://docs.oracle.com/javase/**specs/jls/se7/html/jls-17.**
>> html#jls-17.4<http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4>
>> :
>>
>>    A call to |start()| on a thread /happens-before/ any actions in the
>>    started thread.
>>
>> <comment>
>> But does that guarantee that construction of objects whose references will
>> be written to final fields (guaranteed after construction completes) in the
>> constructor of an object that starts that thread, will happen before or
>> after the new thread is started?  Remembering the jvm is free to not
>> initialize and reorder something it doesn't think it needs now, but must
>> after construction is complete.
>>
>>
>>     
> You gotta stop treating constructors like they're magic!
>
> A constructor has no special semantics in and of itself. It _appears_ like
> it does because there is one "special" thing that can be said of
> construction: It is dispatched within the context of single thread. Two
> separate calls from two separate threads to the constructor are isolated as
> a consequence. Constructors are not atomic, confer nothing in terms of
> ordering, do not represent a synchronization action or have any other
> impact on threading.
>
> So, constructors aren't special, they merely have a set of behaviours
> implied by the language specification. One of those amounts to:
>
> If a programmer does nothing thread-impacting in a constructor, the only
> way any other thread gets to see the object is through the creating thread
> making a reference available to another thread. In which case, there has
> been a synchronization which thus causes the entirety of actions in the
> constructor to be visible all at once. This "all at once" is because the
> constructor must have completed before the reference was made visible to
> another thread.
>
> But *if* a programmer does do some thread stuff in the constructor, then
> normal rules of synchronization apply. Amongst other things that means:
>
> (1) You can't re-order across a synchronization point.
> (2) All changes prior to a synchronization point will be made visible at
> that synchronization point.
>
> start() is a synchronization point and thus anything done before it is made
> visible to all threads once it's completed. Further start() completes
> before the new thread starts (noting that there may be an immediate context
> switch at that point such that the parent thread takes no further action
> but the synchronization has happened prior to the switch).
>
> Thus, all finals initialized prior to calling start() will be visible to
> the new thread. They *may* have been re-ordered for processor performance
> reasons (e.g. to keep pipelines full).
>
>
>
>   
>> So in other words the second thread which started during object
>> construction might not see the objects the first thread has created in a
>> fully constructed state as they haven't yet been published.
>> </comment>
>>
>>    In some cases, such as deserialization, the system will need to
>>    change the |final| fields of an object after construction. |final|
>>    fields can be changed via reflection and other
>>    implementation-dependent means. The only pattern in which this has
>>    reasonable semantics is one in which an object is constructed and
>>    then the |final| fields of the object are updated. The object should
>>    not be made visible to other threads, nor should the |final| fields
>>    be read, until all updates to the |final| fields of the object are
>>    complete. Freezes of a |final| field occur both at the end of the
>>    constructor in which the |final| field is set, and immediately after
>>    each modification of a |final| field via reflection or other special
>>    mechanism.
>>
>>    Even then, there are a number of complications. If a |final| field
>>    is initialized to a compile-time constant expression (ยง15.28
>>    <http://docs.oracle.com/**javase/specs/jls/se7/html/jls-**
>> 15.html#jls-15.28<http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28>
>>     
>>> )
>>>       
>>    in the field declaration, changes to the |final| field may not be
>>    observed, since uses of that |final| field are replaced at compile
>>    time with the value of the constant expression.
>>
>>    Another problem is that the specification allows aggressive
>>    optimization of |final| fields. Within a thread, it is permissible
>>    to reorder reads of a |final| field with those modifications of a
>>    |final| field that do not take place in the constructor.
>>
>>
>>    An implementation may provide a way to execute a block of code in a
>>    /|final|-field-safe context/. If an object is constructed within a
>>    |final|-field-safe context, the reads of a |final| field of that
>>    object will not be reordered with modifications of that |final|
>>    field that occur within that |final|-field-safe context.
>>
>>    A |final|-field-safe context has additional protections. If a thread
>>    has seen an incorrectly published reference to an object that allows
>>    the thread to see the default value of a |final||final|-field-safe
>>    context, reads a properly published reference to the object, it will
>>    be guaranteed to see the correct value of the |final| field. In the
>>    formalism, code executed within a |final|-field-safe context is
>>    treated as a separate thread (for the purposes of |final| field
>>    semantics only).
>>
>>    In an implementation, a compiler should not move an access to a
>>    |final| field into or out of a |final|-field-safe context (although
>>    it can be moved around the execution of such a context, so long as
>>    the object is not constructed within that context).
>>
>>
>>
>>
>> Dan Creswell wrote:
>>
>>     
>>> On 1 April 2013 09:24, Peter Firmstone <jini@zeus.net.au> wrote:
>>>
>>>
>>>
>>>       
>>>> Dan Creswell wrote:
>>>>
>>>>
>>>>
>>>>         
>>>>> On 1 April 2013 08:11, Peter Firmstone <jini@zeus.net.au> wrote:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>           
>>>>>> Food for thought:  After our pending release, it might be an idea
to
>>>>>> make
>>>>>> a combined effort to identify and address as many concurrency issues
as
>>>>>> possible, we need to modernize our implementation code so we stay
>>>>>> relevant.
>>>>>>
>>>>>> An important task will be updating all our service implementations
so
>>>>>> they
>>>>>> DON'T start threads during construction.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>             
>>>>> The ActiveObject pattern often does start threads at construction. I'd
>>>>> like
>>>>> to understand why that is such a problem for you? It surely isn't a big
>>>>> deal for me but....
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>           
>>>> It allows fields to be declared final, if a thread is started during
>>>> construction the JMM makes no guarantee that thread will see the final
>>>> state of that objects fields after construction completes.
>>>>
>>>>
>>>>
>>>>         
>>> Not sure that's true, at least in JDK 7:
>>>
>>> http://docs.oracle.com/javase/**specs/jls/se7/html/jls-17.**html#jls-17.4<http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4>
>>>
>>> "An action that starts a thread *synchronizes-with* the first action in
>>> the
>>> thread it starts. "
>>>
>>> "Two actions can be ordered by a *happens-before* relationship. If one
>>> action *happens-before* another, then the first is visible to and ordered
>>> before the second. "
>>>
>>> "If an action *x* *synchronizes-with* a following action *y*, then we also
>>> have *hb(x, y)*. "
>>>
>>>
>>> i.e. If thread A is doing construction and then starts another thread,
>>> variable assignments prior will be visible to the newly created thread.
>>>
>>> That in turn means so long as all critical assignments are done prior to
>>> starting that second thread, there's no problem?
>>>
>>> And if that's true, starting a thread in a constructor needn't be avoided,
>>> merely done "carefully". Thus it would be sufficient to ensure all final
>>> variables are assigned prior to thread starting, which isn't so hard to do
>>> or assure. I guess my point is, yes there's some care required but
>>> outright
>>> banning thread start() in constructors is overkill.
>>>
>>> ?
>>>
>>>
>>>
>>>
>>>       
>>>> This is important when that thread accesses fields in the constructed
>>>> object.
>>>>
>>>> See:
>>>> https://www.securecoding.cert.****org/confluence/display/java/****
>>>> TSM03-J.+Do+not+publish+****partially+initialized+objects<**
>>>> https://www.securecoding.cert.**org/confluence/display/java/**
>>>> TSM03-J.+Do+not+publish+**partially+initialized+objects<https://www.securecoding.cert.org/confluence/display/java/TSM03-J.+Do+not+publish+partially+initialized+objects>
>>>>         
>>>> https://www.securecoding.cert.****org/confluence/display/java/****
>>>> TSM01-J.+Do+not+let+the+this+****reference+escape+during+**
>>>> object+construction<https://**www.securecoding.cert.org/**
>>>> confluence/display/java/TSM01-**J.+Do+not+let+the+this+**
>>>> reference+escape+during+**object+construction<https://www.securecoding.cert.org/confluence/display/java/TSM01-J.+Do+not+let+the+this+reference+escape+during+object+construction>
>>>>         
>>>> This doesn't mean you can't start a thread during construction, but it
>>>> does mean you must be very careful if you do; our old code isn't that
>>>> careful. ;)
>>>>
>>>> Cheers,
>>>>
>>>> Peter.
>>>>
>>>>
>>>>
>>>>         
>>>
>>>       
>>     
>
>   


Mime
View raw message