views:

61

answers:

6

Hi all,

Consider the following Java code:

volatile boolean v1 = false;
volatile boolean v2 = false;

//Thread A
v1 = true;
if (v2)
    System.out.println("v2 was true");

//Thread B
v2 = true;
if (v1)
    System.out.println("v1 was true");

If there was a globally visible total order for volatile accesses then at least one println would always be reached.

Is that actually guaranteed by the Java Standard? Or is an execution like this possible:

A: v1 = true;
B: v2 = true;
A: read v2 = false;
B: read v1 = false;
A: v2 = true becomes visible (after the if)
B: v1 = true becomes visible (after the if)

I could only find statements about accesses to the same volatile variable in the Standard (but I might be missing something).

"A write to a volatile variable (§8.3.1.4) v synchronizes-with all subsequent reads of v by any thread (where subsequent is defined according to the synchronization order)."

http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.4.4

Thanks!

+1  A: 

The third line in your execution is not possible, due to the fact that v2 is volatile.

If v2 were not volatile, thread A could see a locally-cached copy of v2 that was still false.

Since v2 is volatile, however, every read will go directly to main memory, and will thus see the most recently-written value.

That said, I don't believe there are any specific ordering guarantees between accesses to different global variables, but I also don't believe it makes a difference in your example.

danben
A: 

Well...by the definition of volatile if v2 was set to true by B, then A can't read it as false.

volatile makes data types and references work as expected when threading when doing single opeartions (so ++ and -- don't work!)

Pyrolistical
This is also true for a 64 bit long
John V.
You are correct:http://mindprod.com/jgloss/volatile.html It was changed in Java 1.5
Pyrolistical
A: 

Yes, it does. This question is a duplicate of http://stackoverflow.com/questions/2441279/java-volatile-guarantees-and-out-of-order-execution

Ha
Please post comments as comments rather than answers.
danben
No it's not: In the linked question both writes happen from the same thread!
andreas
@Ha: I asked the question that got 12 votes that you linked and altough highly related, this one is *not* a dupe. In my question the writes to a and b are always happening from the same thread, which I think has its importance here.
Webinator
+1  A: 

I think the quote answers your question more than you realize it does.

The write to v2 by thread B in line #2 is "seen" by thread A when it attempts to read the variable.

I've bolded the key part of the quote:

"A write to a volatile variable (§8.3.1.4) v synchronizes with all subsequent reads of v by any thread ..."

matt b
@matt b: yes but it's more complicated than that: what if a reorder happens in thread A? (seem my answer that is really a comment). I think a reorder in this case is illegal... But that quote certainly doesn't say much about that.
Webinator
a re-ordering of which statements? usually "reordering" applies to re-ordering of statements within a method or block of code to change the sequence of operations. The JVM is only allowed to reorder statements that won't affect subsequent statements. In your threads, the only things to reorder are the assignments and the check of the other variable - a reordering of these two statements within the threads run() block won't affect anything.
matt b
A: 

This too long for a comment (it's just a comment on possible reordering situations) but I think the following is possible if you have only one thread:

A: read v2 = false;
A: v1 = true;

The "read" (the if) can happen before the assignment (if it has no effect on what comes next).

However, in your case there are two threads, so I think the following cannot happen:

A: read v2 = false;
A: v1 = true;
B: read v1 = false;
B: v2 = true;

It's not possible to have this reordering because you have two threads and hence one of these thread could possibly detect the reorder, making that compiler re-ordering illegal.

I asked a question similar but definitely not identical (writing a and b from the same thread, reading from different threads) here:

http://stackoverflow.com/questions/2441279/java-volatile-guarantees-and-out-of-order-execution

Webinator
A: 

The 4 actions, volatile read/write of v1/v2, are all synchronization actions. An execution has a synchronization order over them, which is a total order. The order must keep the program order of each thread.

That makes reasoning very easy. Obviously at least for 1 of the 2 variables, the write to it is ordered before the read from it, in the 'synchronization order'. Therefore, the write 'synchronizes-with' the read. Therefore, the write 'happens-before' the read. Therefore, the write is visible to the read.

irreputable