Several implementations of the thread safe singleton pattern are Shared

  • 2020-04-01 02:57:18
  • OfStack

1, hungry han singleton


public class Singleton {
   private final static Singleton INSTANCE = new Singleton();
   private Singleton() { }
   public static Singleton getInstance() {
      return INSTANCE;
   }
}

2. Use inner classes
This is a lazy singleton because the Java mechanism states that the inner class SingletonHolder is loaded only when the getInstance() method is first called (with lazy implemented) and that the loading process is thread-safe. Instance is instantiated once when the inner class is loaded.


public class Singleton {

   private Singleton() { }
   private static class SingletonHolder {
      private final static Singleton INSTANCE = new Singleton();
   }
   public static Singleton getInstance() {
      return SingletonHolder.INSTANCE;
   }
}

3, common lock solution


public class Singleton {
   private static Singleton instance = null;
   private Singleton() { }

   public static synchronized Singleton getInstance() {
      if(instance == null) {
         instance = new Singleton();
      }
      return instance;
   }
}

Although the thread-safety problem has been solved, each thread calls getInstance with a lock. We want to lock getInstance only on the first call

4, double detection, but pay attention to writing


public class Singleton {
   private static Singleton instance = null;
   private Singleton() { }
   public static Singleton getInstance() {
      if(instance == null) {
         synchronzied(Singleton.class) {
            Singleton temp = instance;
            if(temp == null) {
               temp = new Singleton();
               instance = temp
            }
         }
      }
      return instance;
   }
}
 Due to the instruction reorder problem, it cannot be directly written as follows: 
public class Singleton {
   private static Singleton instance = null;
   private Singleton() { }
   public static Singleton getInstance() {
      if(instance == null) {
         synchronzied(Singleton.class) {
            if(instance == null) {
               instance = new Singleton();
            }
         }
      }
      return instance;
   }
}
 But if the instance Instance variable with volatile Just embellish it, volatile Embellishment ensures that instance = new Singleton(); The corresponding instruction will not be reordered, and the following singleton code is also thread-safe: 
public class Singleton {
   private static volatile Singleton instance = null;
   private Singleton() { }
   public static Singleton getInstance() {
      if(instance == null) {
         synchronzied(Singleton.class) {
            if(instance == null) {
               instance = new Singleton();
            }
         }
      }
      return instance;
   }
}


Related articles: