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