We will present some examples to show how to apply happens-before reasoning to check that writes are visible to subsequent reads.
As you would expect, writes are always visible to subsequent reads in a single-threaded program.
public class SingleThreadExample {
public int a, b;
public int add() {
a = 1; // write(a)
b = 2; // write(b)
return a + b; // read(a) followed by read(b)
}
}
By Happens-Before Rule #1:
write(a) action happens-before the write(b) action.write(b) action happens-before the read(a) action.read(a) action happens-before the read(a) action.By Happens-Before Rule #4:
write(a) happens-before write(b) AND write(b) happens-before read(a) IMPLIES write(a) happens-before read(a).write(b) happens-before read(a) AND read(a) happens-before read(b) IMPLIES write(b) happens-before read(b).Summing up:
write(a) happens-before read(a) relation means that the a + b statement is guaranteed to see the correct value of a.write(b) happens-before read(b) relation means that the a + b statement is guaranteed to see the correct value of b.We will use the following example code to explore some implications of the Memory Model for `volatile.
public class VolatileExample {
private volatile int a;
private int b; // NOT volatile
public void update(int first, int second) {
b = first; // write(b)
a = second; // write-volatile(a)
}
public int observe() {
return a + b; // read-volatile(a) followed by read(b)
}
}
First, consider the following sequence of statements involving 2 threads:
VolatileExample is created; call it ve,ve.update(1, 2) is called in one thread, and