I'm wondering what publication guarantees exist for a non-final field initialised to null, if any.
Consider the following snippet:
public class MyClass {
private final CopyOnWriteArrayList<Inner> list = new CopyOnWriteArrayList<>();
//called by thread 1
public void init() {
// initialise Inner instance
list.add(new Inner());
}
//called by thread 2
public void doSomething() {
for (Inner i : list) {
// access non-final field
Object ref = i.ref;
// do something
// ...
// ...
// potentially set i.ref
}
}
private static class Inner {
// initialised by thread 1
Object ref = null;
}
}
Assuming doSomething()
is always called by thread 2, is this safe? What guarantees are made about what thread 2 will see the first time it's accessed? Is there any possibility thread 2 would see something that's non-null?
Where in the JMM are the semantics around this situation described?
JVM
will guarantee that you don't see out of thin air values, so anything other than null
it not possible, in case that List
is not empty (in this example, of course). If there would have been a different thread involved (let's say Thread3
) that would alter your list (add elements to it), Thread2
could see those updates. Just note that individual methods of CopyOnWriteArrayList
are thread safe; your method doSomething
is not.
See the JLS for the specifics or the excellent (and rather complicated, may be just to me) Aleksey article.