javamultithreadingconcurrencyvolatilejava-memory-model

Volatile happens-before clarification/misunderstanding?


"A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field."

So I know that volatile field can be used as synchronization in order to guarantee that that all the information that thread 1 has before writing to volatile field is going to be visible to thread 2 after reading that volatile.

But what about subsequent writes? Is the behavior the same? Any help appreciated, can't find anything about it in the official docs.

Examples:

### Write -> Read

#Thread1 (Write)
xxx = "anyValue" - any variable with value before volatile
boolean volatile b = true

#Thread2 (Read)
if (b) { -> here we read volatile value
 print(xxx) -> guaranteed visibility of 'xxx' 100%, will print 100% "anyValue"
}

### Write -> Write

#Thread1 (Write)
xxx = "anyValue" - any variable with value before volatile
boolean volatile b = true;

#Thread2 (Write)
b = false; -> here we write to volatile value
print(xxx); -> guaranteed visibility of 'xxx'???, what will be printed?

Solution

  • To give a bit more comprehensive answer by building up the happens-before relation out of its basic orders:

    1. synchronization order: this is the total order of all synchronization actions. Since a volatile write is a synchronization action, the 2 volatile writes to the same or different variables are part of the synchronization order. The synchronization order will even order e.g. the lock of A and the volatile read of B because it is a total order.

    2. synchronizes-with order. This is a partial order that only orders certain synchronization actions. For example, the release of a lock with all subsequent acquires of that same lock and the write of a volatile variable and all subsequent reads of that variable. So 2 volatile writes to different or the same variables are not ordered by the synchronizes-with order.

    3. program order: in simple terms, it is the order as specified by the program code. In your case, the 2 volatiles writes are not ordered by program order since they are issued by different threads.

    Now we get to the last step: the happens-before relation which is an order. It is the transitive closure of the union of the program order and the synchronizes-with order.

    So even though the 2 volatile writes are part of the synchronization order, they are not part of the synchronizes-with order, and as a consequence, they are not part of the happens-before order. So they don't induce any happens-before edges.