I'd like some clarity on what exactly the happens-before property means.
I've seen explanations for the happens-before property say that updates to global variables (which are not volatile or enclosed in a sync block) are made visible to other threads if they are altered before some other variable which is volatile or altered within a sync block. Is this right? If so, where in the java documentation does it say this?
My understanding was that the happens-before property defines the relationship between shared fields and code execution e.g:
- an unlock of a monitor happens-before every subsequent lock of the same monitor.
- a write to a volatile field happens-before every subsequent read of that same field.
- a call to start on a thread happens-before any action in the started thread.
- all actions in a thread happen-before any other thread successfully returns from a join on that thread.
For example:
class Shared {
private int y = 0;
private volatile int x = 0;
public void setOne() {
y = 1;
x = 1;
}
public int getY() {
return y;
}
}
For the code above, given 2 threads:
Shared shared = new Shared();
new Thread(() -> shared.setOne()).start();
new Thread(() -> shared.getY()).start();
Edit Assuming we can guarantee that the first thread has started, would getY() return 0 or 1 here?
I've also seen examples saying that this behavior happens only following a read of a volatile field in a thread. So in that case if one thread reads the value of the volatile field (let's say thread B), then all fields written before that volatile field in thread A are available to thread B. According this, if I modify the getY() method in Shared object from above to be:
public int getXPlusY() {
int local = x;
return local + y;
}
Is it this action that makes y visible to the other thread?