<div class="gmail_quote">On Sat, May 2, 2009 at 9:38 AM, Tim Peierls <span dir="ltr"></span>wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
See more recent discussions in Java Concurrency in Practice, Section 16.2.4 and Effective Java, 2nd edition, Item 71.<div><br></div><div>The fixed version of the code is:</div><div><br></div><div><span style="border-collapse: collapse;"><div>

class SomeClass {</div><div>  private volatile Resource resource;</div><div><br></div><div>  public Resource getResource() {</div><div>    Resource tmp = resource;</div><div>    if (tmp == null) {</div><div>      synchronized (this) {</div>

<div>        tmp = resource;</div><div>        if (tmp == null)</div><div>          resource = tmp = new Resource();</div><div>      }</div><div>    }</div><div>    return tmp;</div><div>  }</div><div>}</div><div><br></div>

</span></div><div><div>--tim</div></div></blockquote><div><br>A clarification of &quot;fixed&quot; that I think Tim would agree with:<br><br>&quot;Fixed&quot; is used in the sense that if you have to have double-check locking, presumably for performance reasons, then this is one of the very few ways to code it correctly.<br>
<br>On the other hand, this &quot;fix&quot; adds even more surface area to the code, and more modifiers for maintainers to contemplate (&quot;volatile&quot;), so as with all optimizations, it is best avoid going this route unless you really need it.<br>
<br>Compiler: In JMM and DCL discussions, the &quot;compiler&quot; refers to javac plus JIT plus anything else that
reorders or optimizes at the instruction level.  In addition to the
compiler(s), the processors and memory system (and anything that might be rigged to run Java apps), can reorder operations --
but only to the extent allowed by the JMM.<br><br>As you surmise, the danger here is that thread B will see a non-null reference to an incompletely constructed resource.<br><br>Joe<br><br>PS - The JMM FAQ could use another update on this topic:<br>

<br>
<a href="http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl">http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl</a><br><br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div><div><div><div></div><div class="h5">On Sat, May 2, 2009 at 12:21 PM, Carol Saah <span dir="ltr"></span>wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

Hello,<br>
<br>
I understand from Brian Goetz that we should NOT use Double-Checked-Locking.<br>
<br>
However, I am trying to understand exactly what can happen in the<br>
incorrectly synchronized code that appears in the article, &quot;Double-checked<br>
locking: Clever, but broken.&quot;  I realize that<br>
<a href="http://www.javaworld.com/jw-02-2001/jw-0209-double.html?page=4" target="_blank">http://www.javaworld.com/jw-02-2001/jw-0209-double.html?page=4</a> is very old<br>
and that some comments may be old; however, the reordering issue is not old.<br>
<br>
The code in question is:<br>
<br>
class SomeClass {<br>
  private Resource resource = null;<br>
<br>
  public Resource getResource() {<br>
    if (resource == null) {<br>
      synchronized (this) {<br>
        if (resource == null)<br>
          resource = new Resource();<br>
      }<br>
    }<br>
    return resource;<br>
  }<br>
}<br>
<br>
On page 4 of the article, &quot;So what&#39;s broken about DCL?&quot;, I would like to get<br>
a more precise description of the 1st scenario discussed in that section.<br>
This is my understanding with questions.<br>
<br>
The reordering discussed in the scenario happens in dynamic compilation and<br>
would seem to happen once and apply to all threads for a class, correct?<br>
<br>
And, does dynamic compilation happen just before JIT?<br>
<br>
In the example, the compiler chooses to reorder the instructions of<br>
getResource() to: allocate memory, assign reference to resource, call<br>
constructor.<br>
<br>
But, in a thread, the as-if-sequential semantics hold, so do those<br>
instructions happen AFTER the thread has done all of its work in the &quot;local<br>
memory.&quot;<br>
<br>
And, do the instructions apply to main memory only?<br>
<br>
Here is the scenario in the example.<br>
<br>
Thread A has invoked getResource() on a someClass object.<br>
<br>
Thread A finds that resource is null and so Thread A invokes the constructor<br>
for Resource and sets the resource.<br>
<br>
Thread A still has not exited the synchronized block so no writes have been<br>
made to main memory.<br>
<br>
Thread A&#39;s state is in its &quot;local memory&quot; on the processor or cache in which<br>
it is running.<br>
<br>
But, before Thread B invokes, getResource(), these &quot;reordered instructions&quot;<br>
happen for Thread A:  allocate memory, assign reference to resource<br>
<br>
Now, Thread B invokes getResource().<br>
<br>
Thread B finds the reference to resource that the &quot;reordered&quot; instructions<br>
from Thread A put into main memory.<br>
<br>
But, in the meantime, the processor executing the instructions for Thread A<br>
still has not caused the constructor to execute in main memory so main<br>
memory has a reference but nothing in it.<br>
<br>
So, is this why Thread B is partially constructed?<br>
<br>
Thanks.<br>
<br>
Carol Saah<br>
<br>
</blockquote></div></div></div></div></div></blockquote></div><br>