The first play of single example mode -- lazy type
Lazy, this method can only be initialized when getInstance needs to be called, which has the advantage of saving memory space to some extent. But there is also a disadvantage that it is not safe in a multithreaded environment. The code is as follows:
/** * Lazy mode, i.e. initialization when needed * Not safe in the case of multithreading */ public class LazySingleton { private static LazySingleton instace = null; private LazySingleton() { } public static LazySingleton getInstace() { if (instace == null) { instace = new LazySingleton(); } return instace; } }
Test results under multithreading
Although it is simple, we find that it is not secure (the address of the instance is obviously wrong).
The second bullet of single case mode -- double check lock mode
In fact, double check lock is the advanced version of lazy mode. You're not safe, so I'll make you safe. The code is as follows
/** * Double check lock to realize the singleton mode is actually the lazy singleton of the Security version * * If you don't join volatile, you may have problems * instance = new DoubleCheckSingleton();There are three steps * 1.Open up memory space in heap memory. * 2.Instantiate the parameters in SingleTon in heap memory. * 3.Point the object to the heap memory space. * Due to the optimization of jvm, the execution may be out of order. For example, if it is executed before 3:2, other threads will make errors when they get it */ public class DoubleCheckSingleton { private static volatile DoubleCheckSingleton instance = null; private DoubleCheckSingleton(){} public static DoubleCheckSingleton getInstance(){ if(instance==null){ synchronized (DoubleCheckSingleton.class){ if(instance == null){ instance = new DoubleCheckSingleton(); } } } return instance; } }
The third bullet of single case mode -- starving Han mode
The starved man mode, as you can see by its name, is loaded directly on the first step, so as to avoid thread insecurity, but there will also be a memory problem. The code is as follows
/** * The starved Chinese singleton mode will be instantiated at the beginning, which is thread safe */ public class HangerSingleton { private static HangerSingleton instance = new HangerSingleton(); private HangerSingleton() { } public static HangerSingleton getInstance() { return instance; } }
The fourth bullet of singleton mode -- static inner class
Since the dislike starved mode does not have the function of lazy loading, the static internal classes can fully meet this function, which is not only lazy loading, but also safe. The code is as follows
/** * When external classes are loaded for the first time, static internal classes will not be loaded. Instances will not be instantiated until getInstance is called, and smart will load them once * */ public class StaticInnerSingleton { private StaticInnerSingleton() { } private static class StaticInnerSingletonHoler { private static StaticInnerSingleton instance = new StaticInnerSingleton(); } public static StaticInnerSingleton getInstance() { return StaticInnerSingletonHoler.instance; } }
The fifth bullet of singleton pattern -- Enumeration class
Although static inner class is very good, but I also dislike the code is too long, how to do??? Then use enumeration directly. Enumeration naturally has the feature of singleton. How refreshing.
public enum EnumSingleton { instance; }
above.....