title: Double checked locking in modern JVMs
body: <p>I have a class that might throw any run-time exceptions during initialization. I want the class to be a singleton since the cost of keeping several objects in memory is high. I am using that class in another class. </p>
  
  <p>My use case is as follows:</p>
  
  <ul>
  <li>I have to use a single instance of <code>Controller</code>.</li>
  <li>Each instance of <code>Parent</code> must use the same <code>Controller</code> instance.</li>
  <li><code>Controller</code>
  constructor might throw exceptions. </li>
  <li>If instantiation fails, I should
  retry to instantiate after sometime.</li>
  </ul>
  
  <p>So I check if my Controller instance is <code>null</code> when I try to do a "get" on the <code>Controller</code>, if yes, I try to instantiate it again.</p>
  
  <p>Following is my code:</p>
  
  <pre><code>class Parent
  {
      private static volatile Controller controller;
      private static final Object lock = new Object();
  
      static
      {
          try
          {
              controller = new Controller();
          }
          catch(Exception ex)
          {
              controller = null;
          }
      }
  
      private Controller getController() throws ControllerInstantiationException
      {
          if(controller == null)
          {
              synchronized(lock)
              {
                  if(controller == null)
                  {
                      try
                      {
                          controller = new Controller();
                      }
                      catch(Exception ex)
                      {
                          controller = null;
                          throw new ControllerInstatntationException(ex);
                      }
                  }
              }
          }
          return controller;
      }
  
      //other methods that uses getController() 
  }
  </code></pre>
  
  <p>My question is, is this code broken? I read somewhere that the above code would be a problem in JVM 1.4 or earlier. Can you provide references/solutions? Please note that I am asking this question because there is a lot of confusion regarding this topic in the internet.</p>
  
  <p>Thanks.</p>