I've looked at this answer, and it states how:
Under the new memory model, when thread A writes to a volatile variable V, and thread B reads from V, any variable values that were visible to A at the time that V was written are guaranteed now to be visible to B.
Therefore, given the example:
public class Main {
static int value = -1;
static volatile boolean read;
public static void main(String[] args) {
Thread a = new Thread(() -> {
value = 1;
read = true;
});
Thread b = new Thread(() -> {
while (!read);
System.out.println("Value: " + value);
});
a.start();
b.start();
}
}
Is the change to value
(from -1 to 1) guaranteed to be visible to thread b despite the non-volatility of value
(only read
)?
If so, given a bunch of changes that are performed with the intention of being visible to another thread, is there any purpose in making any variable changed other than the last one volatile?
Yes, the change to
value
is guaranteed to be visible to thread b.JLS 17.4.4. Synchronization Order says:
JLS 17.4.5. Happens-before Order says:
Bullet 1 says that
value = 1
happens-beforeread = true
.Bullet 3 says that
read = true
happens-before!read
.Bullet 1 says that
!read
happens-before"Value: " + value
.Bullet 4 says that
value = 1
happens-before"Value: " + value
.