Definition
Ensure that there is only one instance of a class in any case, such as in a running container, privatize the constructor, and provide a global access point.
Implementation mode
1. Hungry Han style
public class HungrySingleton { private static final HungrySingleton INSTANCE = new HungrySingleton(); private HungrySingleton() { } public static HungrySingleton getInstance() { return INSTANCE; } } public class HungrySingletonB { private static final HungrySingletonB INSTANCE ; static{ INSTANCE = new HungrySingletonB(); } private HungrySingletonB() { } public static HungrySingletonB getInstance() { return INSTANCE; } }
Starved Chinese is to instantiate the object when the class is loaded.
2. Slovenly
public class LazySingleton { private static LazySingleton INSTANCE = null; public LazySingleton() { } public static synchronized LazySingleton getInstance() { if (INSTANCE == null) { INSTANCE = new LazySingleton(); } return INSTANCE; } }
Lazy is to instantiate an object when calling the getInstance method of a class. Due to the consideration of multithreading, we need to add synchronized synchronization lock to every method call, so the performance is relatively low.
3. Double detection lock
public class DoubleCheckSingleton { private static volatile DoubleCheckSingleton INSTANCE = null; public DoubleCheckSingleton() { } public static DoubleCheckSingleton getInstance() { if (INSTANCE == null) { synchronized (DoubleCheckSingleton.class) { if (INSTANCE == null) { INSTANCE = new DoubleCheckSingleton(); } } } return INSTANCE; } }
Double detection lock is to detect whether there is an instantiated object first when calling getInstance, and then instantiate the object if not. Considering multithreading, instance variables are decorated with volatile, and the visibility of virtual machine to variables and synchronized synchronization lock are used to ensure the uniqueness of instantiation. The performance is higher than that of lazy type.
4. Static inner class
public class StaticInnerSingleton { public StaticInnerSingleton() { } public static StaticInnerSingleton getInstance() { return InnerClass.INSTANCE; } private static class InnerClass { private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton(); } }
The static inner class instantiates the inner class object InnerClass when the getInstance method is called for the first time. Because of the use of final decoration, it is thread safe.
5. Enumerative
public enum EnumSingleton { INSTANCE; public static EnumSingleton getInstance() { return INSTANCE; } }
Enumerative is a single instance object registered during class initialization, so it is also a single instance implementation of registered type.
6. Container type
public class ContainerSingleton { public ContainerSingleton() { } private static Map<String, Object> IOC = new ConcurrentHashMap<>(); public static Object getBean(String className) { synchronized (IOC) { if (!IOC.containsKey(className)) { try { Class<?> aClass = Class.forName(className); Object o = aClass.newInstance(); IOC.put(className, o); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } } return IOC.get(className); } }
Container is also a lazy way of implementation. The difference is that container puts the instantiated objects in the Map container for centralized management, which is also a registered simple profit implementation. Spring's IOC is this way of implementation.
7. Local line program
public class ThreadLocalSingleton { private static final ThreadLocal<ThreadLocalSingleton> threadLocal = new ThreadLocal<ThreadLocalSingleton>() { [@Override](https://my.oschina.net/u/1162528) protected ThreadLocalSingleton initialValue() { return new ThreadLocalSingleton(); } }; public static ThreadLocalSingleton getInstance() { return threadLocal.get(); } }
Local threading ensures the uniqueness of instantiated objects in a single thread.