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 thannull
it not possible, in case thatList
is 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),Thread2
could see those updates. Just note that individual methods ofCopyOnWriteArrayList
are thread safe; your methoddoSomething
is not.See the JLS for the specifics or the excellent (and rather complicated, may be just to me) Aleksey article.