Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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 {{flag}} 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]\] 
The field flag is not required to be volatile because the initialization is being carried out in a static initializer and is guaranteed to finish before the object becomes usable.

Similar to this noncompliant code example, threads should not be started from constructors. See CON14-J. Do not let the "this" reference escape during object construction for more information.

...

Code Block
bgColor#ccccff
public class Lazy {
  private static boolean flag = false;  

  private static final ThreadLocal<Connection> connectionHolder
    = new ThreadLocal<Connection>() {
        public Connection initialValue() {
          try {
            Connection conn = DriverManager.getConnection("connectionstring");
            flag = true;
	          return conn;
	      } catch (SQLException e) {
	          return null;
	        }
      }
  }
  };
    
  public static Connection getConnection() {
    return connectionHolder.get();
  }

  public static void main(String[] args) {
    Connection conn = getConnection();
    System.out.println(flag);
  }
}

...