Does making a class field volatile
prevent all memory visibility issues with it in a concurrent situation ? Is it possible that for below class , a thread that gets a reference of a Test
object sees x
as 0 first ( the default value of int
) and then 10 ? I am thinking this to be possible if and only if the Constructor of Test
gives away this
reference without completing ( improper publishing ) . Can someone validate/correct me ?
class Test {
volatile int x = 10;
}
Second question: what if it was final int x=10;
?
You are actually not guaranteed to see x = 10 according to the JMM.
For example if you have
Test test = null;
Thread 1 -> test = new Test();
Thread 2 -> test.x == // even though test != null, x can be seen as 0 if the
// write of x hasn't yet occur
Now if you had
class Test{
int y = 3;
volatile x = 10;
}
If thread-2 reads x == 10 thread-2 is guaranteed to read y == 3
To answer your second question.
Having a final field will issue a storestore after the constructor and before publishing so having the field final will actually ensure you see x = 10.
Edit: As yshavit noted. You lose the happens-before relationship I mention in my first example with final fields, that is as yshavit put it if thread-2 reads x == 10 it may not read y == 3 where x is a final field.
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