...
This makes the originally proposed double-checked locking pattern insecure. The guideline CON26-J. Do not publish partially initialized objects further discusses the possible occurrence possibility of a non-null reference that refers to a Helper
object that observes default values of fields in the Helper
partially initialized object.
Compliant Solution (volatile
)
...
Code Block | ||
---|---|---|
| ||
final class Foo { private static final Helper helper = new Helper(); public static Helper getHelper() { return helper; } } |
Wiki Markup |
---|
Variables that are declared {{static}} and initialized at declaration or from a static initializer, are guaranteed to be initializedfully constructed andbefore instantlybeing made visible to other threads. Static initializers also exhibit these properties. This approach should not be confused with eager initialization because in this case, the Java Language Specification \[[JLS 05|AA. Java References#JLS 05]\] guarantees lazy initialization of the class when it is first used \[[JLS 05|AA. Java References#JLS 05]\]. |
Compliant Solution (initialize-on-demand holder class idiom)
...
Wiki Markup |
---|
Initialization of the {{Holder}} class is deferred until the {{getInstance()}} method is called, following which the {{helper}} field is initialized. The only limitation of this method is that it works only for {{static}} fields and not for instance fields \[[Bloch 01|AA. Java References#Bloch 01]\]. This idiom is a better choice than the double checked locking idiom for lazily initializing {{static}} fields \[[Bloch 08|AA. Java References#Bloch 08]\]. |
...
While this code ensures that only one Helper
object is preserved from being garbage collected, it may potentially allow allows multiple Helper
objects to be created, with all but one being garbage-collected. However, if . If constructing multiple Helper
objects is infeasible or expensive, this solution may be inappropriate unless a weak reference is used to hold Helper
.
Compliant Solution (immutable
)
...