Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>My understanding is that the reason <code>wrapper</code> is used is that reading an immutable object (all fields are final) is an atomic operation.</p> <p>If <code>wrapper</code> is null, then it's not yet an immutable object, and we have to fall into the <code>synchronized</code> block.</p> <p>If <code>wrapper</code> is not-null then we are <em>guaranteed</em> to have a fully constructed <code>value</code> object, so we can return it.</p> <p>In your code, the <code>null</code> check could be done without actually reading the referenced object, and so not triggering the atomicity of the operation. I.e. the operation could have initialized <code>helperWrapper</code> in preparation for passing the result of <code>new Helper()</code> to the constructor, but the constructor has not been called yet.</p> <p>Now I would presume that the subsequent code in your example would read <code>return helperWrapper.value;</code> which <em>should</em> trigger an atomic reference read, guaranteeing that the constructor completes, but it's entirely possible ('<em>semantics of some programming languages</em>') that the compiler is allowed to optimize that to not perform an atomic read, and thus it would return an incompletely initialized <code>value</code> object under the exact right circumstances.</p> <p>Performing the barrier using a local variable and a reference copy forces the read and write to be atomic, and ensures that the code is thread-safe.</p> <p>I believe the key understanding is that immutable reference reads and writes are atomic, so assignment to another variable is atomic, but null testing might not be.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload