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?
JVMwill guarantee that you don't see out of thin air values, so anything other thannullit not possible, in case thatListis not empty (in this example, of course). If there would have been a different thread involved (let's sayThread3) that would alter your list (add elements to it),Thread2could see those updates. Just note that individual methods ofCopyOnWriteArrayListare thread safe; your methoddoSomethingis not.See the JLS for the specifics or the excellent (and rather complicated, may be just to me) Aleksey article.