[concurrency-interest] Volatile happens before question

David Holmes davidcholmes at aapt.net.au
Tue Jan 17 17:50:14 EST 2012


Raph Frank writes:
> I was wondering if there was a happens before guarantee for reads of
> volatiles relative to later writes.  I think maybe not, but it isn't
> clear.

The specification defines all the happens-before orderings that exist - see
JLS 17.4.5 for the definitions of happens-before, and 17.4.4 for the defined
synchronization actions. In terms of your question a volatile write
happens-before subsequent reads of the same variable. There is no
happens-before ordering between a volatile read and a subsequent volatile
write.

> For example, assuming there were 2 threads with the following code:
>
> ** Thread 1 **
>
> int b = 0;
> volatile boolean a = false;
> ...
> ...
> a = true;
> b = 1;
>
> ** Thread 2 **
>
> int bStore = b;
> if (!a) {
>   System.out.println("The value of bStore is " + bStore);
> }
>
> Are these reasonable statements:
>
> "bStore = b" happens-before "if(!a)"

Yes - these are actions in the same thread and so happens-before order
follows program order

> "if(!a)" happens-before "a = true;" [Assuming that (!a) evaluates to true]

No. You need to be careful about "happens-before" vs. "occurred before". The
former is a clearly defined property in the memory-model. The latter is the
actual occurrence at execution time. If !a evaluates to true then it is
certainly the case that the read of 'a' occurred prior to the write a=true.
But there is no happens-before edge between the two actions.

> "a = true;" happens-before "b=1;"

Yes - these are actions in the same thread and so happens-before order
follow program order

> Thus, the program will either print "The value of bStore is 0" or not
> print anything.

No. You lost the transitive relationship of happens-before with your second
statement. Your code can be reordered and executed as follows:

    Thread 1                    Thread 2
                                if (!a) // sees false
    a = true
    b = 1;
                                bStore =b;
                                print   // prints 1

Or as Vitaly states, the assignments in Thread 1 could appear reordered when
seen from Thread 2

Cheers,
David Holmes




More information about the Concurrency-interest mailing list