Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added ThreadLocal CS

...

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
bgColor#ccccff

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.

...