Preface
Hello everyone, I am very smart. A design pattern is a set of code design experiences that have been used repeatedly, are known to most people, and are classified and cataloged. The purpose of using design patterns is to reuse code, make the code easier to understand by others, and ensure code reliability.
Today I will share some relevant knowledge points about the singleton pattern, hoping it will be helpful to you.
Definition of singleton pattern
The singleton pattern is a commonly used creational design pattern that contains only a special class called a singleton in its core structure. The singleton pattern can ensure that there is only one object instance for a class using the singleton pattern in the system.
Characteristics of singleton pattern
- A singleton class can only have one instance.
- A singleton class must create its own unique instance.
- A singleton class must provide this instance to all other objects
Hungry Chinese style
The characteristic of Hungry Style is that the object instance is already created during initialization, regardless of whether you have used it or not. The specific code is as follows:
public class HungrySingleton {
// 持有自己类的引用
private static final HungrySingleton singleton = new HungrySingleton();
// 私有化构造器
private HungrySingleton(){}
// 提供获取实例的静态方法
public static HungrySingleton getInstance(){
return singleton;
}
}
Advantages: No thread safety issues
Disadvantages: Creating objects during the initialization phase, assuming that instantiating the object is very time-consuming, and this instance is not used in the end, wouldn’t it be a waste of resources?
lazy man style
The characteristic of the lazy style is that the object is instantiated only when it is used. It is relatively lazy . When it is used, it will check whether there is an instance. If there is an instance, it will be returned directly. If not, it will be created and then returned. The specific code is as follows:
public class LazySingleton {
private static LazySingleton singleton;
// 私有化构造器
private LazySingleton(){}
// 提供获取实例的静态方法
public static LazySingleton getInstance(){
// 若对象没有被实例化,则new一下再返回
if (singleton == null) {
singleton = new LazySingleton();
}
return singleton;
}
}
Advantages: The object will only be instantiated when it is used
Disadvantages: The biggest problem with this implementation is that it is not thread-safe. Since there is no lock, multiple objects may be instantiated in concurrent situations.
Double detection lock
As the name suggests, double detection lock uses a double judgment lock mechanism , which is safe and can maintain high performance in multi-threaded situations . It is equivalent to an upgraded version of the lazy style. The specific code is as follows:
public class DoubleCheckLockingSingleton {
// 注意这里多了一个volatile关键字,面试的时候经常会问这个关键字的作用
private volatile static DoubleCheckLockingSingleton singleton;
// 私有化构造器
private DoubleCheckLockingSingleton(){}
// 提供获取实例的静态方法
public static DoubleCheckLockingSingleton getInstance(){
if (singleton == null) {
synchronized (DoubleCheckLockingSingleton.class) {
if (singleton == null) {
singleton = new DoubleCheckLockingSingleton();
}
}
}
return singleton;
}
}
Advantages: Suitable for use in high concurrency situations, ensuring thread safety
Disadvantages: Singletons can be destroyed through reflection
static inner class
As the name suggests, static inner classes implement singleton mode through static inner classes. This method can achieve the same effect as double detection locks. The specific code is as follows:
public class StaticInnerClassSingleton {
// 静态内部类
private static class SingletonHolder {
private static final StaticInnerClassSingleton singleton = new StaticInnerClassSingleton();
}
// 私有化构造器
private StaticInnerClassSingleton(){}
// 提供获取实例的静态方法
public static StaticInnerClassSingleton getInstance() {
return SingletonHolder.singleton;
}
}
Advantages: Thread safety, using the characteristics of static inner classes to achieve delayed loading, high efficiency
Disadvantages: Singletons can be destroyed through reflection
enumerate
In Java, enumerations are natural singletons . Each instance has only one object. This is a guarantee provided by Java's underlying internal mechanism.
public enum EnumSingleton {
INSTANCE;
}
Advantages: JVM ensures that the enumeration is a natural singleton, thread-safe, automatically supports the serialization mechanism, prevents deserialization from re-creating new objects, and prevents multiple instantiations.
Summarize
There are many ways to implement the singleton mode, which are compared from three aspects: whether it is thread-safe, whether it is lazy loading, and whether it prevents reflection construction, as follows:
Singleton pattern implementation | Is it thread safe? | Whether to lazy load | Whether to prevent reflective builds |
---|---|---|---|
Hungry Chinese style | yes | no | no |
lazy man style | no | yes | no |
Double detection lock | yes | yes | no |
static inner class | yes | yes | no |
enumerate | yes | no | yes |
The singleton pattern is often encountered during interviews and work. What design patterns do you often use in your work? Feel free to leave a message below.
Friends who like this article, then you must like this article! Then give it a like!