Lazy singleton mode
Code implementation:
public class SingletonMode { private static SingletonMode instance=null; //Privatize the construction method to prevent external instantiation private SingletonMode(){} public static SingletonMode getInstance(){ if(instance==null){ instance =new SingletonMode();//Can only be instantiated internally } return instance; } }
characteristic:
1. As soon as the class is loaded, it will be instantiated. It takes up memory space whether it is used or not, so it sometimes causes memory leakage.
2. No lock, high execution efficiency, better experience than lazy mode
3. Thread unsafe [if(instance==null)] may instantiate multiple objects
How to become thread safe? A: add a synchronization lock
public class SingletonMode { private static SingletonMode instance=null; //Privatize the construction method to prevent external instantiation private SingletonMode(){} public static synchronized SingletonMode getInstance(){ if(instance==null){ instance =new SingletonMode();//Can only be instantiated internally } return instance; } }
However, this will introduce new problems. We only want to synchronize threads during object construction. In this way, we also need to synchronize threads every time we get objects, which has a great impact on performance. In actual development, this is not recommended.
If, we adopt the following methods:
public class SingletonMode { private static SingletonMode instance=null; //Privatize the construction method to prevent external instantiation private SingletonMode(){} public static SingletonMode getInstance(){ if(instance==null){//1 synchronized(SingletonMode.class){//2 instance =new SingletonMode();//Only internal instantiation 3 is allowed } return instance;//4 } }
If this method is adopted, threads a, b and C enter 1. At this time, if a, b and C all perform empty judgment, if a obtains the lock, releases the lock after an instance, b enters and instantiates, multiple objects are instantiated. Therefore, this operation is not feasible.
If you do the following:
public class SingletonMode { private static SingletonMode instance=null; //Privatize the construction method to prevent external instantiation private SingletonMode(){} public static SingletonMode getInstance(){ if(instance==null){//1 synchronized(SingletonMode.class){//2 if(instance==null){ instance =new SingletonMode();//* }//Only internal instantiation 3 is allowed } return instance;//4 } }
Double space determination avoids the above problems, but * operation is non atomic operation, * this line of code is divided into three steps: 1. Allocate memory, 2. Initialize object, 3. Object points to memory address. During real execution, the virtual opportunity rearranges the three-step instructions (example: 1-3-2). This is thread unsafe. If the object has not been initialized in step 3, another thread will enter and an object will be instantiated. So we should do this:
public class SingletonMode { private static volatile SingletonMode instance=null; //Privatize the construction method to prevent external instantiation private SingletonMode(){} public static SingletonMode getInstance(){ if(instance==null){//1 synchronized(SingletonMode.class){//2 if(instance==null){ instance =new SingletonMode();//* }//Only internal instantiation 3 is allowed } return instance;//4 } }
volatile can prevent the instruction rearrangement problem acting on instance. This code is the final version of lazy singleton mode (double check lock)
Hungry Han single case mode
public class SingleyonMode2 { public static SingleyonMode2 singletonMode=new SingleyonMode2(); private SingleyonMode2(){}//Prevent instantiation from outside public static SingleyonMode2 getInstance(){ return singletonMode; } }
This method instantiates an object at compile time.
characteristic:
1. As soon as the class is loaded, it will be instantiated. It takes up memory space whether it is used or not, so it sometimes causes memory leakage.
2. No lock, high execution efficiency, better experience than lazy mode
This method is thread safe
Other methods
Other methods to implement singleton mode:
Use static inner classes:
public class InnerClassMode { //Static inner class private static class SingletonHolder{ private static final InnerClassMode INSTANCE=new InnerClassMode(); } private InnerClassMode(){}; public static final InnerClassMode getInstance(){ return SingletonHolder.INSTANCE; } }
The inner class is not loaded when the outer class is loaded, but only when it is first called.
Please criticize and correct any mistakes in the article