Wechat search: Menon StayUp
Home address: https://gozhuyinglong.github.io
Source code sharing: https://github.com/gozhuyinglong/blog-demos
1. Singleton mode
Singleton Pattern is a simple object creation pattern. This pattern ensures that a class has only one instance and provides a global access point to access it.
Therefore, to realize the singleton mode, the following points should be achieved:
- Privatize the construction method and eliminate the use of constructors to create instances.
- You need to create a unique instance and provide a global access entry
2. Several implementations of singleton mode
There are five implementations for singleton mode.
2.1. Lazy style
This method uses the synchronized keyword to lock to ensure thread safety.
Advantages: initialize only after the first call, avoiding memory waste.
Disadvantages: locking the method of obtaining instances greatly reduces the concurrency efficiency.
The lock has a great impact on the performance and is not recommended.
public class SingletonLazy { /** * Private instance */ private static SingletonLazy instance; /** * Private construction method */ private SingletonLazy() { } /** * The only method that exposes an instance (static factory method), which uses synchronized locking to ensure thread safety * * @return */ public static synchronized SingletonLazy getInstance() { if (instance == null) { instance = new SingletonLazy(); } return instance; } }
2.2 hungry Han style
Hungry Han style uses the class loading mechanism to avoid the synchronization problem of multithreading, so it is thread safe.
Advantages: unlocked, high execution efficiency.
Disadvantages: the instance is initialized when the class is loaded, resulting in a waste of memory.
If the memory requirement is not high, this method is recommended.
public class SingletonEager { /** * Private instances and static variables will be initialized when the class is loaded, which is thread safe */ private static final SingletonEager instance = new SingletonEager(); /** * Private construction method */ private SingletonEager() { } /** * The method that uniquely exposes the instance (static factory method) * * @return */ public static SingletonEager getInstance() { return instance; } }
2.3 double check lock
The thread visibility of volatile modifier is used (after being modified by one thread, other threads will be visible immediately), which ensures lazy loading and high performance, so it is recommended.
public class SingletonDCL { /** * For private instances, variables modified by volatile are visible (that is, after being modified by one thread, other threads will be visible immediately) */ private volatile static SingletonDCL instance; /** * Private construction method */ private SingletonDCL() { } /** * The method that uniquely exposes the instance (static factory method) * * @return */ public static SingletonDCL getInstance() { if (instance == null) { synchronized (SingletonDCL.class) { if (instance == null) { instance = new SingletonDCL(); } } } return instance; } }
2.4 static internal class
This mode uses the static internal class delay initialization feature to achieve the same function as the double check lock mode. Because auxiliary classes are needed, they are not often used.
public class SingletonInnerClass { /** * Private construction method */ private SingletonInnerClass() { } /** * The method that uniquely exposes the instance (static factory method) * * @return */ public static SingletonInnerClass getInstance() { return LazyHolder.INSTANCE; } /** * Private static inner class */ private static class LazyHolder { private static final SingletonInnerClass INSTANCE = new SingletonInnerClass(); } }
2.5 enumeration class
This method makes use of the characteristics of enumeration classes, which can not only avoid the problem of thread synchronization, but also prevent deserialization and re creation of new objects. This approach is advocated by Josh Bloch, author of Effective Java.
However, because this coding method can not adapt, it is rarely used in practical work.
public enum SingletonEnum { INSTANCE; public void method() { System.out.println("Methods defined in enumeration class!"); } }
Recommended reading
- < Singleton mode >
- < Strategy mode >