I'm reading "Java concurrency in practice", and it says:
To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:
- Initializing an object reference from a static initializer;
- Storing a reference to it into a volatile field or AtomicReference;
- Storing a reference to it into a final field of a properly constructed object; or
- Storing a reference to it into a field that is properly guarded by a lock.
What I don't understand is "Storing a reference to it into a final field of a properly constructed object", Why is "of a properly constructed object" needed? Without "of a properly constructed object", can other threads see the object that is being published in an inconsistent state?
I have read several related questions:
- final vs volatile guaranntee w.rt to safe publication of objects - Stack Overflow
- safe publication of mutable object - Stack Overflow
But I can't find much explanation about Why "of a properly constructed object" is needed.
Below example comes from an answer in question "final vs volatile guaranntee w.rt to safe publication of objects - Stack Overflow"
class SomeClass{
private final SomeType field;
SomeClass() {
new Thread(new Runnable() {
public void run() {
SomeType copy = field; //copy could be null
copy.doSomething(); //could throw NullPointerException
}
}).start();
field = new SomeType();
}
}
SomeClass is not properly constructed, of course, copy could be null, but in my opinion, the thread can not see the copy in an inconsistent state, either copy is null or "both the reference to the copy and the copy's state must be made visible to the threads at the same time". So, field is published safely even though SomeClass is not properly constructed. Am I right?
Hope someone can give me more explanation, thanks in advance.