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.