Six ways to realize the singleton pattern

Six ways to realize the singleton pattern

1. Hungry Chinese style in singleton mode [available]

//饿汉式实现单例模式
public class Hungry {
    
    

    private Hungry(){
    
    }

    private  static Hungry hungry = new Hungry();

    public static Hungry getHungry(){
    
    
        return hungry;
    }
}

Advantages: simple implementation, instantiation is completed when the class is loaded, avoiding thread synchronization problems.
Disadvantages: delay loading cannot be implemented, which may cause a waste of memory (the waste can be ignored)

2. The lazy style of singleton mode [not available]

//懒汉式实现单例模式
public class LazySingleton01 {
    
    

    private LazySingleton01(){
    
    }

    private static LazySingleton01 lazy ;

    public static LazySingleton01 getLazy(){
    
    
        if(lazy==null){
    
    
            return new LazySingleton01();
        }
        return lazy;
    }
}

Disadvantages: thread is not safe, not recommended

Process with thread safety issues: There may be such a situation in the running process, there are multiple threads to call the getLazy method to obtain the LazySingleton01 instance, it may happen, the first thread is executing if(lazy = =null) When new LazySingleton01() has not been executed, the lazy obtained by the second thread is also null. After passing the judgment of (lazy==null), both threads will eventually have new instances.

3. The lazy man + synchronization method of singleton mode [not recommended]

//懒汉式+同步方法实现单例模式
public class LazySingleton02 {
    
    
    private LazySingleton02(){
    
    }

    private static LazySingleton02 lazy;

    public static synchronized LazySingleton02 getLazy(){
    
    
        if(lazy==null){
    
    
            return new LazySingleton02();
        }
        return lazy;
    }
}

Thread safe, low efficiency is not recommended

For the improvement of the above defects, some people may think of the following code:

public class LazySingleton03 {
    
    
    private LazySingleton03(){
    
    }

    private static LazySingleton03 lazy;

    public static  LazySingleton03 getLazy(){
    
    
        if(lazy==null){
    
    
        	synchronized(LazySingleton03.class){
    
    
            	return new LazySingleton03();
            }
        }
        return lazy;
    }
}

This writing method is also thread-unsafe. When a thread has not instantiated LazySingleton03, another thread will enter the if statement when it executes the judgment statement if (lazy==null). Although the lock is added, it waits until the first When a thread executes lazy=new LazySingleton03() to release the lock, another thread that enters the if statement will also instantiate another LazySingleton03 object.

After step-by-step exploration, there is a lazy writing method of double check lock:

4. The lazy style of singleton mode + double check lock [recommended]

//双重校验锁+懒汉式
public class DoubleCheckSingleton {
    
    
    private DoubleCheckSingleton(){
    
    }
    
    private volatile static DoubleCheckSingleton instance;
    
    public static DoubleCheckSingleton getInstance(){
    
    
        if(instance==null){
    
    
            synchronized (DoubleCheckSingleton.class){
    
    
                if(instance==null){
    
    
                    return new DoubleCheckSingleton();
                }
            }
        }
        return instance;
    }
}

Advantages: thread safety, lazy loading, higher efficiency

Note the volatile here:

//双重校验锁+懒汉式
public class DoubleCheckSingleton {
    
    
    private Socket socket;

    private DoubleCheckSingleton(){
    
    
        this.socket=new Socket();
    }
    
    private volatile static DoubleCheckSingleton instance;
    public static DoubleCheckSingleton getInstance(){
    
    
        if(instance==null){
    
    
            synchronized (DoubleCheckSingleton.class){
    
    
                if(instance==null){
    
    
                    return new DoubleCheckSingleton();
                }
            }
        }
        return instance;
    }
}

According to the JVM runtime instruction reordering and Happens-Before rules, the order of instantiation between instance and socket has no relational constraints. Whoever comes first is possible. If the instance is instantiated first, then socket is Will not be instantiated, calling this method will produce a null pointer exception------>

The solution to this is very simple. Adding a keyword volatite
can ensure that the relative position of the instantiation order remains unchanged. The instance instantiation is always after the socket.

5. Static inner class of singleton mode [recommended use]

//静态内部类实现单例模式
public class StaticInner {
    
    

    private StaticInner(){
    
    }

    private static class inner{
    
    
        private static StaticInner instance=new StaticInner();
    }

    public static StaticInner getInstance(){
    
    
        return inner.instance;
    }
}

Advantages: Avoid thread insecurity, lazy loading, and high efficiency.
Detailed explanation: This method does not declare the static member of instance in advance, but puts it in the static inner class inner, which defines the static variable and directly performs the instance When inner is actively referenced, an instance will be created. StaticInner is collected in the () method during instance creation. This method is a synchronous method that
guarantees memory visibility, sequential execution and atomicity of JVM instructions. This method is also one of the best designs of singleton mode.

6. Enumeration of singleton mode [recommended use]

//枚举实现单例模式
public enum EnumSingleton {
    
    
    INSTANCE;

    private EnumSingleton(){
    
    }

    public void method(){
    
    }
}

Use the enumeration added in JDK1.5 to realize the singleton mode.
Advantages: Not only can avoid multi-thread synchronization problems, but also prevent deserialization from re-creating new objects. The implementation is very simple and the safest is perfect.

Guess you like

Origin blog.csdn.net/AIHUAya/article/details/109242786