4

I am new to Java, I am currently learning about volatile. Say I have the following code:

public class Test
{
    private static boolean b = false;

    public static void main(String[] args) throws Exception
    {
        new Thread(new Runnable()
        {
            public void run()
            {
                while(true) 
                {
                    b = true;   
                }
            }
        }).start();

        // Give time for thread to start
        Thread.sleep(2000);

        System.out.println(b);
    }
}

Output:

true

This code has two threads (the main thread and another thread). Why is the other thread able to modify the value of b, shouldn't b be volatile in order for this to happen?

James
  • 703
  • 8
  • 17
  • @fillpant The link you gave me (and from what I know), `volatile` guarantees that the variable is not cached locally. So in my code because I am not using `volatile`, the variable should be cached locally, but this is not happening, the modification by the other thread is seen by the main thread!! – James Jun 20 '15 at 16:56
  • check this answer [http://stackoverflow.com/questions/4934913/are-static-variables-shared-between-threads](http://stackoverflow.com/questions/4934913/are-static-variables-shared-between-threads). It says that, even if variable is not marked as volatile , if write operation happens before read operation of any other thread, updated static variables will be visible to other threads, which is the case in your code since you are calling sleep on main thread for 2 seconds, which is more than sufficient time. Remove sleep call and you may see sporadic results – Amit.rk3 Jun 20 '15 at 17:03

2 Answers2

4

The volatile keyword guarantees that changes are visible amongst multiple threads, but you're interpreting that to mean that opposite is also true; that the absence of the volatile keyword guarantees isolation between threads, and there's no such guarantee.

Also, while your code example is multi-threaded, it isn't necessarily concurrent. It could be that the values were cached per-thread, but there was enough time for the JVM to propagate the change before you printed the result.

RichW
  • 2,004
  • 2
  • 15
  • 24
3

You are right that with volatile, you can ensure/guarantee that your 2 threads will see the appropriate value from main memory at all times, and never a thread-specific cached version of it.

Without volatile, you lose that guarantee. And each thread is working with its own cached version of the value.

However, there is nothing preventing the 2 threads from resynchronizing their memory if and when they feel like it, and eventually viewing the same value (maybe). It's just that you can't guarantee that it will happen, and you most certainly cannot guarantee when it will happen. But it can happen at some indeterminate point in time.

The point is that your code may work sometimes, and sometimes not. But even if every time you run it on your personal computer, is seems like it's reading the variable properly, it's very likely that this same code will break on a different machine. So you are taking big risks.

sstan
  • 35,425
  • 6
  • 48
  • 66