...
Wiki Markup |
---|
This idiom is called the initialize-on-demand holder class idiom. Initialization of the {{Holder}} class is deferred until the {{getInstance()}} method is called, following which the {{helper}} is initialized. The only limitation of this method is that it works only for {{static}} fields and not 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]\]. |
Compliant Solution (ThreadLocal
storage)
Wiki Markup |
---|
This compliant solution (originally suggested by Alexander Terekhov \[[Pugh 04|AA. Java References#Pugh 04]\]) uses a {{ThreadLocal}} object to lazily create a {{Helper}} instance. |
Code Block |
---|
|
class Foo {
// If perThreadInstance.get() returns a non-null value, this thread
// has done synchronization needed to see initialization of helper
private final ThreadLocal perThreadInstance = new ThreadLocal();
private Helper helper = null;
public Helper getHelper() {
if (perThreadInstance.get() == null) {
createHelper();
}
return helper;
}
private final void createHelper() {
synchronized(this) {
if (helper == null) {
helper = new Helper();
}
// Any non-null value would do as the argument here
perThreadInstance.set(perThreadInstance);
}
}
}
|
Exceptions
EX1: Explicitly synchronized code (that uses method synchronization or proper block synchronization, that is, enclosing all initialization statements) does not require the use of double-checked locking.
...