Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<blockquote> <p>As far as I understand condition must be volatile since even with the synchronized block, the compiler will not issue any memory barriers; if it were a volatile store to condition in setTrue the compiler would issue StoreEnter.</p> </blockquote> <p>That is not correct. When you use a shared variable within a <code>synchronized</code> block, your code will be thread-safe with respect to other threads using the same variable with the same lock. If memory barriers are required, then they will be used.</p> <p>However, the code you have shown us is <em>is incorrect</em> because the <code>setTrue()</code> method is updating the flag outside of a <code>synchronized</code> block.</p> <hr> <blockquote> <p>Am I right to believe the above is susceptible to data races?</p> </blockquote> <p>Yea ... sort of. The scenario is as follows:</p> <ol> <li>The condition is <code>false</code>.</li> <li>Some other thread calls <code>setTrue</code> which sets the condition variable to <code>true</code> in its cache. But since the <code>setTrue</code> method doesn't use <code>synchronized</code>, there is no write barrier, and no flushing to main memory. </li> <li>The "example" thread fetches the latest committed value from main memory (which is still <code>false</code>), and doesn't wait as it is supposed to do.</li> </ol> <blockquote> <p>Also, I believe the use of notifyAll is overkill here since there is one condition to check and only one thread will ever be waiting on it, right?</p> </blockquote> <p>It could be replaced with a <code>notify()</code> ... if that is what you mean. But to be honest, it makes no real difference which flavour of notify you use.</p> <hr> <p>You commented:</p> <blockquote> <p>I meant that the compiler would not consider it necessary to submit a memory barrier in this situation.</p> </blockquote> <p>Maybe. But the "monitorenter" and "monitorexit" instructions implicitly involve memory barriers.</p> <p>And:</p> <blockquote> <p>Wouldn't it also be correct if condition were volatile?</p> </blockquote> <p>If you are talking about using <code>volatile</code> AND <code>synchronized</code>, then yes it would be correct ... though the <code>volatile</code> would be redundant (assuming that the <code>setTrue</code> bug is fixed.)</p> <p>If you are talking about <code>volatile</code> only, then no. You can't implement an efficient "wait on a condition variable" with just <code>volatile</code>. The problem is that neither the "read/test/wait" or "write/notify" sequences can be performed atomically; i.e. without the possibility of race-conditions. </p> <p>And besides, you can't do the equivalent of <code>wait/notify</code> without using a primitive object mutex, or a <code>Lock</code> object.</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