Detailed explanation of common modes of singleton mode

Definition of singleton pattern

The singleton pattern is a design pattern used to ensure that there is only one instance of a class and provide a global access point to obtain that instance.

In the singleton pattern, the constructor of a class is made private so that no other class can directly create an instance of that class. Instead, get the only instance of the class through a static method or property.

Classification of singleton patterns

There are many ways to implement the singleton pattern in Java, here are the two most common

hungry man mode

The following is the specific implementation:


public class Singleton {
    
    
    //此处,先把实例创建出来
    private static  Singleton instance=new Singleton();

    //如果需要使用这个唯一实例,统一通过 Singleton.getInstance()方法来获取。
    public static Singleton getInstance(){
    
    
        return  instance;
    }

    //为了避免Singleton 类不小心被复制出多份来
    //把构造方法设置为private.在类外面,就无法通过new的方式来创建这个Singleton实例
    private Singleton(){
    
    

    }
}

insert image description here

herestaticIt plays a vital role:

  • static guarantees that this instance is unique
  • static ensures that this instance is indeed created at a certain time.
    The static modification makes the current instance attribute a class attribute. The class attribute is on the class object. The class object is unique in a java process (it is only created during the class loading phase. an instance)

Supplementary knowledge points :
Class loading:
Each class in the java code will get a .class file after compilation. When the JVM runs, it will load this .class file, read the binary instructions in it, and construct the corresponding class object in memory. (Shape like Singleton.class)

insert image description here

  • Set the constructor toprivate, Outside the class, this instance cannot be created by new.

The advantage of the hungry man mode is that it is simple to implement,thread safety, because the instance is created when the class is loaded. But the disadvantage is that if the instance is not used during the entire program running, it will cause waste of resources.

lazy mode

The following is the specific implementation:

public class SingletonLazy {
    
    

    private static  SingletonLazy instance=null;

    public static SingletonLazy getInstance(){
    
    
        if(instance==null){
    
    
            instance=new SingletonLazy();
        }
        return instance;
    }

    private SingletonLazy(){
    
    

    }

}

insert image description here

The lazy mode does not initialize when the class is loaded, but decides whether to create an instance by judging whether the instance already exists when the instance of the class is used for the first time. ( Lazy instantiation, creating a unique instance only when needed .)

The advantage of the lazy man mode is that it is simple to implement, and instances are only created when needed, avoiding resource waste. But the disadvantage is that in a multi-threaded environment it mayA thread safety issue arises, requires additional processing.

How to make the above lazy pattern thread-safe? Perform a lock operation
insert image description here

due to the use ofsynchronizedkeyword, which may affect performance. To improve performance, you can usedouble check lockingetc. to optimize.

The above code will cause each getInstance() operation to be locked. The locking operation has overhead. However, if the value of the instance is judged to be non-null, the return operation will be directly triggered. Since there is no modification operation at this time, it is unnecessary lock.

as follows:
insert image description here

To avoid memory visibility problems and instruction reordering problems that the above code may encounter, usevolatileKeyword optimization.
code show as below:

public class SingletonLazy {
    
    
    private volatile static  SingletonLazy instance=null;

    public static SingletonLazy getInstance(){
    
    

        if (instance == null) {
    
    
            synchronized (SingletonLazy.class) {
    
    
                if (instance == null) {
    
    
                    instance = new SingletonLazy();
                }
            }
        }

        return instance;
    }

    private SingletonLazy(){
    
    
    }

}

The main characteristics of the singleton pattern

  • Private constructor: Prevent other classes from directly creating instances by making the constructor private.
  • Static instance variable: Define a static instance variable inside the class to save the only instance of the class.
  • Static access method: Provide a static method or property for obtaining the only instance of the class. This method creates an instance the first time it is called and returns the same instance on subsequent calls.

Application Scenarios of the Singleton Pattern

  • Only one instance of an object of a certain class in the system needs to exist, such as configuration information class, logging class, etc.
  • Scenarios that require frequent creation and destruction of objects can save system resources by using the singleton pattern.
  • Scenarios where objects need to be shared or accessed globally, such as thread pools, database connection pools, etc.

Summarize

When implementing the singleton pattern, you need to pay attention to the issues of thread safety and lazy loading. You can use locks, double-check locks, etc. to ensure thread safety, and create instances only when needed to avoid resource waste.

Guess you like

Origin blog.csdn.net/m0_63904107/article/details/131731589