Design pattern
1, Singleton mode
characteristic:
-
A singleton class can only have one instance
-
A singleton class must create its own unique instance
-
Singleton classes must provide this instance to all other objects
solve the problem:
-
A global class is frequently created and destroyed
1. Lazy mode
public class SingletonOne { private SingletonOne() {} private static SingletonOne instance = null; public static SingletonOne getInstance() { // Thread safety exists here if (instance == null) { instance = new SingletonOne(); } return instance; } }
2. Starving Han model
public class Singleton2 { private Singleton2() {} private static Singleton2 instance = new Singleton2(); // Class loading is slow public static Singleton2 getInstance() { return Singleton2.instance; } }
3. Dual check mode (DCL)
public class Singleton3 { private Singleton3() {} private static Singleton3 instance = null; public static Singleton3 getInstance() { if (null == instance) { // JVM Thread safety caused by instruction rearrangement of compiler synchronized (Singleton3.class) { if (instance== null) { instance= new Singleton3(); } } } return instance; } }
4. Double check mode - optimized version
public class Singleton4 { private Singleton4() {} // volatile Keyword disallows reordering of instructions private volatile static Singleton4 instance = null; public static Singleton4 getInstance() { if (null == instance) { synchronized (Singleton4.class) { if (instance== null) { instance= new Singleton4(); } } } return instance; } }
5. Static internal class
/** * 1.The static inner class LazyHolder cannot be accessed from outside, only when the Singleton.getInstance Method to get the INSTANCE object INSTANCE. * 2.INSTANCE The time of object initialization is not when Singleton is loaded, but when getInstance method is called to load the static inner class LazyHolder. * So this way is to use the loading mechanism of classloader to achieve lazy loading and ensure the thread safety of building a single instance. */ public class Singleton5 { private Singleton5() {} private static class LazyHolder { private static final Singleton5 INSTANCE = new Singleton5(); } public static Singleton5 getInstance() { return LazyHolder.INSTANCE; } }
5.1 reflection breaks the constraint of singleton mode
//Get constructor Constructor con = Singleton5.class.getDeclaredConstructor(); //Set to accessible con.setAccessible(true); //Construct two different objects Singleton5 singleton1 = (Singleton5)con.newInstance(); Singleton5 singleton2 = (Singleton5)con.newInstance(); //Verify different objects System.out.println(singleton1); System.out.println(singleton2); // result singleton.Singleton5@4554617c singleton.Singleton5@74a14482
6. Enumeration
// Prevent using reflection to forcibly build singleton objects public enum Singleton6 { INSTANCE; public void doSomething(){ } }
7. Summary
realization | Thread safety | Lazy load | Prevent reflection build |
---|---|---|---|
Lazy mode | no | yes | no |
Starved Han model | yes | no | no |
Double check mode | yes | yes | no |
Static inner class | yes | yes | no |
enumeration | yes | no | yes |
Note: generally, the 1st and 2nd lazy way is not recommended, and the 4th hungry way is recommended. The fifth static inner class approach is only used if you want to explicitly implement the lazy loading effect. If deserialization is involved in creating objects, try the sixth enumeration.
8. Supplement
-
Volatile keyword can not only prevent instruction rearrangement, but also ensure that the variable value accessed by thread is the latest value in main memory. I will explain the detailed principle of volatile in the future comics.
-
The singleton pattern implemented by enumeration can not only prevent the singleton object from being constructed by reflection, but also ensure that the return result of the deserialization is the same object when the enumeration class object is deserialized.
-
For the singleton pattern implemented by other methods, if you want to be both serializable and deserialized to the same object, you must implement the readResolve method.