Question: Is this statement true: „A write to a volatile field happens-before every subsequent read of that or another volatile field.“
On How to understand happens-before consistent I found the following statements:
Happens-before: „Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second.“
Volatile: „A write to a volatile field happens-before every subsequent read of that field.“
Visibility: „When Thread A changes/writes a volatile variable it also pushes all previous changes into RAM - Main Memory as a result all not volatile variable will be up to date and visible for another threads“.
In the following program, according to the java memory model, it is not guaranteed that the output "thread end" will appear on the console:
public class VolatileQuestion {
static boolean finish = false;
public static void main(String[] args) throws Exception {
new Thread(() -> {
while (!finish);
System.out.println("thread end");
}).start();
Thread.sleep(2000);
finish = true;
System.out.println("main end");
}
}
Declaring field „finish" as volatile it is guaranteed that the output "thread end" will appear on the console:
public class VolatileQuestion {
static volatile boolean finish = false;
public static void main(String[] args) throws Exception {
new Thread(() -> {
while (!finish);
System.out.println("thread end");
}).start();
Thread.sleep(2000);
finish = true;
System.out.println("main end");
}
}
In the third program, I don't declare field finish as volatile, but I introduce another field declared as volatile, which the main thread writes and the other thread reads. Therefore, according to the java memory model, the output of "thread end" is guaranteed:
public class VolatileQuestion {
static boolean finish = false;
static volatile boolean flush = false;
public static void main(String[] args) throws Exception {
new Thread(() -> {
while (!finish) {
boolean dummy = flush;
}
System.out.println("thread end");
}).start();
Thread.sleep(2000);
finish = true;
flush = true;
System.out.println("main end");
}
}
And now my question: What happens if I write a volatile field in the main thread and read another volatile field in the other thread: Is the output of "thread end" guaranteed in that case too?
public class VolatileQuestion {
static boolean finish = false;
static volatile boolean flush = false;
static volatile boolean refresh = false;
public static void main(String[] args) throws Exception {
new Thread(() -> {
while (!finish) {
boolean dummy = refresh;
}
System.out.println("thread end");
}).start();
Thread.sleep(2000);
finish = true;
flush = true;
System.out.println("main end");
}
}