An abstract/snippet from Java Concurrency In Practice-
// Unsafe publication
public Holder holder;
public void initialize(){
holder = new holder(42);
}
Two things can go wrong with improperly published objects. Other threads could see a stale value for the holder field, and thus see a null reference or other older value even though a value has been placed in holder. But far worse, other threads could see an up-todate value for the holder reference, but stale values for the state of the Holder. To make things even less predictable, a thread may see a stale value the first time it reads a field and then a more up-to-date value the next time, which is why assertSanity can throw AssertionError.
Also object reference becomes visible to another thread does not necessarily mean that the state of that object is visible to the consuming thread
public class Holder{
private int n;
public Holder(int n) {
this.n = n;
}
public void assertSanity(){
if (n != n)
throw new AssertionError("This statement is false.");
}
}
Ofcouse, one of the ways to fix it would be to do/ make
public volatile Holder holder;
The author suggests a different approach-
If Holder were immutable, assertSanity could not throw AssertionError, even if the Holder was not properly published.)
public class Holder{
private final int n;
//...
}
But how? The unsafe publication is still there. I think it is still possible for a thread to get a null reference on holder. Please suggest.