[design mode - singleton mode]

Definition and application scenario

Singleton mode refers to ensuring that a class has only one instance and provides a global access point. The singleton pattern is a creation pattern. The application scenarios are as follows:

  1. Connection pool
  2. applicationContext in spring

Several ways of writing singleton mode

Hungry Han style single case

Hungry Han singleton mode is initialized when the class is loaded and creates a singleton object. It is thread safe because it has been initialized when the class is loaded and cannot appear before the thread appears

//Hungry Han style
public class HungrySingleton{
	private static final HungrySingleton lan=new HungrySingleton();
	private HungrySingleton (){}
	//Global access point
	public static HungrySingleton getInstance(){
		return lan;
	}
}

Disadvantages: initializing the object when the class is loaded may cause a waste of memory.

Static inner class singleton

Static internal classes can solve the memory waste caused by the above lazy type, which can ensure lazy loading and thread safety.

public class StaticInnerClassSingleton{
	private static class SingletonHolder{
		private static final StaticInnerClassSingleton INSTANCE=new StaticInnerClassSingleton();
	}
	private StaticInnerClassSingleton(){
		//Single case of preventing reflection damage
		if(SingletonHolder.INSTANCE!=null){
			throw new RuntimeException("Multiple singletons are not allowed");
		}
	}
	//Global access point
	public static final StaticInnerClassSingleton getInstance(){
		return SingletonHolder.INSTANCE;
	}
}

Lazy single case

The lazy singleton is lazy as its name. It will be initialized only when it is used. Let's see the simple implementation below

//Lazy single case
public class LazySingleton(){
	private static LazySingleton lazy=null;
	private LazySingleton (){}
	public static LazySingleton getInstance(){
		//Two threads entering this method may cause thread insecurity
		if(lazy==null){
			lazy=new LazySingleton();
		}
		return lazy;
	}
}

Disadvantages: in the case of multithreading, two threads may enter the if method at the same time. Both threads enter the if judgment successively and return the value successively.

Double check lock

When there is a lazy singleton with unsafe thread, some people will say that adding synchronized keywords to class methods will lead to a large range of locks and low efficiency, so there is a double check lock. The simple implementation is as follows:

public class DouSingleton{
	private static DouSingleton singleton;
	private DouSingleton(){}

	public static DouSingleton getInstance(){
		if(singleton==null){
			synchronized(DouSingleton.class){
				if(singleton==null){
					singleton=new DouSingleton ();
				}
			}
		}
		return singleton;
	}
}

Disadvantages: it may cause null pointer exceptions. The solution is to add volatile keyword to the singleton object. If you are not clear, please search for knowledge about java memory model. Here is a brief explanation. Creating objects is divided into three steps: A. opening up space; b. Initialization object information; c. Returns the address of the object to the reference. Volatile is to prevent reordering of these three steps. Thread 1 executes step ab, and thread 2 determines that the object = = null is false, which directly returns the object, resulting in the object being empty.

Singleton and serialization

public class Singleton implements Serializable{
	private static Singleton singleton;
	private Singleton(){}

	public static Singleton getInstance(){
		if(singleton==null){
			synchronized(Singleton.class){
				if(singleton==null){
					singleton=new Singleton ();
				}
			}
		}
		return singleton;
	}
	//Just override this method.
	private Object readResolve(){
		return singleton;
	}
}

Enumerative singleton

This method is advocated by the author of Effective Java. It can avoid the problem of multi-threaded synchronization and prevent deserialization and re creation of new objects.

public enum EnumSingleton{
	INSTANCE;
	EnumSingleton(){}
	public static EnumSingleton getInstance(){
		return INSTANCE;
	}
}

Tags: Java Singleton pattern

Posted on Sun, 05 Dec 2021 20:53:48 -0500 by georgen