It is an example from JCiP.
public class Unsafe {
// Unsafe publication
public Holder holder;
public void initialize() {
holder = new Holder(42);
}
}
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.");
}
}
}
On page 34:
[15] The problem here is not the Holder class itself, but that the Holder is not properly published. However, Holder can be made immune to improper publication by declaring the n field to be final, which would make Holder immutable;
And from this answer:
the specification for final (see @andersoj's answer) guarantees that when the constructor returns, the final field will have been properly initialized (as visible from all threads).
From wiki:
For example, in Java if a call to a constructor has been inlined then the shared variable may immediately be updated once the storage has been allocated but before the inlined constructor initializes the object
My question is:
Because : (could be wrong, I don't know.)
a) the shared variable may immediately be updated before the inlined constructor initializes the object.
b) the final field will be guaranteed to be properly initialized (as visible from all threads) ONLY when the constructor returns.
Is it possible that another thread sees the default value of holder.n
? (i.e. Another thread gets a reference to holder
before the holder
constructor returns.)
If so, then how do you explain the statement below?
Holder can be made immune to improper publication by declaring the n field to be final, which would make Holder immutable
EDIT: From JCiP. The definition of an immutable object:
An object is immutable if:
x Its state cannot be modified after construction;x All its fields are final;[12] and
x It is properly constructed (the this reference does not escape during construction).
So, by definition, immutable objects don't have "this
reference escaping" problems. Right?
But will they suffer from Out-of-order writes in double-checked-locking pattern if not declared to be volatile?