<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>all that jazzvolatile</title>
    <link>http://jazzy.id.au/default/tags/volatile/</link>
    <description>james' blog about java and all that jazz</description>
    <language>en</language>
    <copyright>James Roper</copyright>
    <pubDate>Sat, 12 May 2012 07:02:00 GMT</pubDate>
    <dc:creator>James Roper</dc:creator>
    <dc:date>2012-05-12T07:02:00Z</dc:date>
    <dc:language>en</dc:language>
    <dc:rights>James Roper</dc:rights>
    <image>
      <title>all that jazzvolatile</title>
      <url>http://jazzy.id.au/default/tags/volatile/</url>
    </image>
    <item>
      <title>Java Concurrency and Volatile</title>
      <link>http://jazzy.id.au/default/2009/04/24/java_concurrency_and_volatile.html</link>
      <content:encoded>&lt;p&gt;
The volatile keyword is a keyword that very few Java developers know the meaning of, let alone when they should use it.  The reason for this, I believe, is that the reason why it's needed is such a complex topic that unless you've studied in detail the way CPUs use registers, cache, and the way the JVM uses stack frames, it's impossible to understand why it's needed.  The other reason I think, is that it is difficult to demonstrate the consequences of not using it.  That is why I came up with this little puzzle, to highlight how important the volatile keyword is.
&lt;/p&gt;

&lt;p&gt;
For this demonstration, you will need a multi processor Linux 2.6 or OpenSolaris system, with Java 5 or above.  It will not work on Mac or Windows.  If you know why it doesn't work on Mac or Windows, please leave a comment explaining, I'd really like to know.  What this does highlight though is just how complex Java concurrency issues are.
&lt;/p&gt;

&lt;p&gt;
So on to the puzzle.  Without executing it, try and work out what will happen when you run the following code:
&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
public class ConcurrencyFun implements Runnable
{
    private String str;
    void setStr(String str)
    {
        this.str = str;
    }
    public void run()
    {
        while (str == null);
        System.out.println(str);
    }
    public static void main(String[] args) throws Exception
    {
        ConcurrencyFun fun = new ConcurrencyFun();
        new Thread(fun).start();
        Thread.sleep(1000);
        fun.setStr("Hello world!!");
    }
}
&lt;/pre&gt;

&lt;p&gt;
Most people would guess that the above code would wait for about one second, print the text "Hello world!!", and then exit.  The spawned thread busy waits for &lt;tt&gt;str&lt;/tt&gt; to not be null, and then prints it.  The main thread, after starting the spawned thread, waits for one second, and then sets &lt;tt&gt;str&lt;/tt&gt; to be "Hello world!!".  Simple, right?
&lt;/p&gt;

&lt;p&gt;
Now try running it (remember, only on a multi processor Linux 2.6 or Solaris system).  What actually happens?  On my machine, the program never exits.  Why is this?
&lt;/p&gt;

&lt;p&gt;
The reason is that the JVM is free to make its own copy of the &lt;tt&gt;str&lt;/tt&gt; pointer available to each thread that uses it.  This could come in many forms.  It could be that the pointer is loaded into a register and is continually read from that register.  This is what is most likely happening in our case.  It could be that the pointer is loaded into the CPU cache, and never expired, even after update.  Or, it is also possible that the JVM will make a copy of the pointer in the threads stack frame, to allow for more efficient memory access.  Whether you understand anything I've just said or not, the point is that changes to the &lt;tt&gt;str&lt;/tt&gt; field may not necessarily be seen by all threads accessing it, in our case, it will never be seen by the spawned thread.
&lt;/p&gt;

&lt;p&gt;
This is where the volatile keyword comes in.  The volatile keyword tells the JVM that any writes to that field must be viewable by all threads.  This means that the compiled machine code may not read the variable into a register and use that multiple times, it must read it from memory every time.  It also must not read it from the CPU cache, it must make sure that every read comes straight from memory.  And finally, it stops the JVM from creating a local copy of the field in the threads stack frame.
&lt;/p&gt;

&lt;p&gt;
So, adding the volatile keyword, like so:
&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
public class ConcurrencyFun implements Runnable
{
    private volatile String str;
    void setStr(String str)
    {
        this.str = str;
    }
    public void run()
    {
        while (str == null);
        System.out.println(str);
    }
    public static void main(String[] args) throws Exception
    {
        ConcurrencyFun fun = new ConcurrencyFun();
        new Thread(fun).start();
        Thread.sleep(1000);
        fun.setStr("Hello world!!");
    }
}
&lt;/pre&gt;

&lt;p&gt;
results in the expected behaviour happening, the program waits one second, prints out "Hello world!!" and then exists.
&lt;/p&gt;

&lt;h3&gt;The complexity of concurrency&lt;/h3&gt;

&lt;p&gt;
There are other ways to make the above code work.  For example, if in the while loop, you add some code that prints something out, you will find that it works.  My guess at the reason for this is that the register storing &lt;tt&gt;str&lt;/tt&gt; ends up getting used for something else, and so on each iteration, &lt;tt&gt;str&lt;/tt&gt; gets read from memory.  Note that this is not a real fix, it is still possible for problems to occur, and indeed on some architectures the program still will not exit.  Another thing that will work is to invoke Java with the &lt;tt&gt;-Xint&lt;/tt&gt; argument.  This disables machine code compilation, and hence makes concurrency issues arising from registers and CPU caches much less likely.  But again, it's not a solution.  Using the volatile keyword is the only solution that guarantees that it will work, every time, on every platform.
&lt;/p&gt;</content:encoded>
      <category domain="http://jazzy.id.au/default/categories/java/">Java</category>
      <category domain="http://jazzy.id.au/default/tags/concurrency/">concurrency</category>
      <category domain="http://jazzy.id.au/default/tags/java/">java</category>
      <category domain="http://jazzy.id.au/default/tags/volatile/">volatile</category>
      <pubDate>Thu, 23 Apr 2009 23:41:00 GMT</pubDate>
      <guid isPermaLink="false">tag:jazzy.id.au,2009-04-23:default/1240530060000</guid>
      <dc:date>2009-04-23T23:41:00Z</dc:date>
    </item>
  </channel>
</rss>


