Note that there are some explanatory texts on larger screens.

plurals
  1. POVolatile guarantees and out-of-order execution
    text
    copied!<p><strong>IMPORTANT EDIT</strong> I know about the "happens before" <em>in the thread where the two assignments are happening</em> my question is would it be possible for <em>another</em> thread to be reading "b" non-null while "a" is still null. So I know that if you're calling <em>doIt()</em> from the same thread as the one where you previously called <em>setBothNonNull(...)</em> then it cannot throw a NullPointerException. But what if one is calling <em>doIt()</em> <strong>from another thread</strong> than the one calling <em>setBothNonNull(...)</em> ?</p> <p>Note that this question is solely about the <code>volatile</code> keyword and the <code>volatile</code> guarantees: it is <strong>not</strong> about the <code>synchronized</code> keyword (so please don't answer "you must use synchronize" for I don't have any issue to solve: I simply want to understand the <code>volatile</code> guarantees (or lack of guarantees) regarding out-of-order execution).</p> <p>Say we have an object containing two <code>volatile</code> String references that are initialized to null by the constructor and that we have only one way to modify the two String: by calling <em>setBoth(...)</em> and that we can only set their references afterwards to non-null reference (only the constructor is allowed to set them to null).</p> <p>For example (it's just an example, there's no question yet):</p> <pre><code>public class SO { private volatile String a; private volatile String b; public SO() { a = null; b = null; } public void setBothNonNull( @NotNull final String one, @NotNull final String two ) { a = one; b = two; } public String getA() { return a; } public String getB() { return b; } } </code></pre> <p>In <em>setBothNoNull(...)</em>, the line assigning the non-null parameter "a" appears before the line assigning the non-null parameter "b".</p> <p>Then if I do this (once again, there's no question, the question is coming next):</p> <pre><code>doIt() { if ( so.getB() != null ) { System.out.println( so.getA().length ); } } </code></pre> <p>Am I correct in my understanding that due to out-of-order execution I can get a <em>NullPointerException</em>?</p> <p>In other words: there's no guarantee that because I read a non-null "b" I'll read a non-null "a"?</p> <p>Because due to out-of-order (multi)processor and the way <code>volatile</code> works "b" could be assigned before "a"? </p> <p><code>volatile</code> guarantees that reads subsequent to a write shall always see the last written value, but here there's an out-of-order "issue" right? (once again, the "issue" is made on purpose to try to understand the semantics of the <code>volatile</code> keyword and the Java Memory Model, not to solve a problem).</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