Search code examples
javaconcurrencyjvmvisibilityvolatile

Volatile variable and non volatile reordering / visibility


So I thought I knew this stuff well enough, until I read something which got me doubting my knowledge on this subject matter. I am almost certain the book is incorrect but would like to ask the community as well.

PS: Have not seen the errata of the book so could well be disclosed as an error.

A simplified example:

public class VolatileMain {

private volatile int a = 0;
private String text = "";

public static void main(String[] args) throws Exception {

    VolatileMain vm = new VolatileMain();

    Thread writer = new Thread() {

        @Override
        public void run() {
            System.out.println("Running thread " + Thread.currentThread().getName());
            vm.text = "hello world";
            vm.a = 5;
        }
    };

    writer.start();
    writer.join();

    System.out.println("Running thread " + Thread.currentThread().getName());
    System.out.println(vm.a);
    System.out.println(vm.text);

   }

}

So given the example is it correct to assume that the write to "text" by Thread writer is guaranteed to be visible by any other thread that reads it?

It seems the author is piggy backing on the volatile semantics of the variable "a" and ensuring that the write to "text" will also be flushed when "a" is flushed, is this a guarantee?

I didn't think it was, but my own quick test (above) to the contrary

Your thoughts.


Solution

  • is it correct to assume that the write to "text" by Thread writer is guaranteed to be visible by any other thread that reads it?

    No. But it's guaranteed to be visible by any other thread that reads a before reading text, as your example does:

    • the write of text happens-before the write to a in the writer thread
    • the write of a in writer happens-before the read of a in the main thread
    • the happens-before relation is transitive
    • hence the the write of text happens before the read of a.