Here:
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
Are the same guarantees held for the volatile
field?
What if the y
field in the following example would be volatile
could we observe 0
?
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
}
Yes, it is possible to see 0
when
class FinalFieldExample {
final int x;
volatile int y;
static FinalFieldExample f;
...
}
The short explanation:
writer()
thread publishes f = new FinalFieldExample()
object via a data racereader()
thread is allowed see f = new FinalFieldExample()
object as semi-initialized.reader()
thread can see a value of y
that was before y = 4;
— i.e. initial value 0
.More detailed explanations are here.
You can reproduce this behavior on ARM64 with this jcstress test.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With