The singleton pattern is not simple

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

  1. A singleton class can only have one instance.
  2. A singleton class must create its own unique instance.
  3. 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.

—————END—————

​ Friends who like this article, then you must like this article! Then give it a like!

Guess you like

Origin blog.csdn.net/qq_41917138/article/details/126112168