Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: s/flag/number in the first two code samples

...

Code Block
bgColor#FFcccc
public class Lazy {
  private static boolean flag = falseint number;
  static {
    Thread t = new Thread(new Runnable() {
      public void run() {
        // Initialize, for example, a database connection
        flagLazy.this.number = true42;
      }
    });
    
    t.start();
    try {
      t.join();
    } catch(InterruptedException ie) {
        throw new AssertionError(ie);
    }
    // Other initialization
  }
  public static void main(String[] args) {
    System.out.println(flagnumber);
  }
}

Wiki Markup
The code in the {{static}} block is responsible for initialization, and starts a background thread. The background thread attempts to assign to the {{flagnumber}} but needs to wait before initialization of the {{Lazy}} class has finished. Remember that statically-initialized fields are guaranteed to be fully constructed before becoming visible to other threads (see [CON26-J. Do not publish partially initialized objects] for more info). Consequently the background thread must wait for the foreground thread to finish initialization before it may proceed. However, the {{Lazy}} class's main thread invokes the {{join()}} method which waits for the background thread to finish. This interdependency causes a class initialization cycle that results in a deadlock situation. \[[Bloch 05b|AA. Java References#Bloch 05b]\] 

...

Code Block
bgColor#ccccff
public class Lazy {
  private static boolean flag = falseint number;
  
  static {
    // Initialize, for example, a database connection
    flagthis.number = true42;
  }
  
  public static void main(String[] args) {
    System.out.println(flagnumber);
  }
}

Compliant Solution (ThreadLocal)

...