In fact, you are not guaranteed to see x = 10 according to 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 have
class Test{ int y = 3; volatile x = 10; }
If thread-2 reads x == 10, thread-2 is guaranteed to read y == 3
To answer the second question.
After the final field, you will get the repository after the constructor and before publishing, so the end of the field actually guarantees that you will see x = 10.
Edit: As noted by Ishavit. You lose the connection between the events that I mention in my first example with finite fields, i.e. as yshavit, put it if thread-2 reads x == 10, it might not read y == 3, where x is the final field.
source share