当前位置:网站首页>Talk about singleton mode!

Talk about singleton mode!

2022-06-25 23:51:00 Program diary

The singleton pattern

Definition

Ensure that a class has only one instance , And provide the global access point of the instance , This class can only be new once , And I use it every time new This .

Class structure

A private constructor , A private static instance variable , A public static function , Used to get instances .

Private constructor : Can not let others create

Common static functions : The global access point for this instance , Returns the unique private static instance variable

Concrete realization

Slacker type - Thread unsafe

The lazy type creates the return object only when it is used , It will not be created when it is not needed , But there are also thread unsafe problems

Thread unsafe : Multiple threads access the acquisition object for the first time at the same time , Both are judged to be empty , And then new The object , Result in multiple instantiations of the object

public class Singleton {
    

    private static Singleton uniqueInstance;

    private Singleton(){
    

    }

    public static Singleton getUniqueInstance(){
    
        if (uniqueInstance == null){
    
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}
Slacker type - Thread safety

How to solve the lazy thread insecurity problem ? Make it thread safe , You only need to lock the instance when you get it , In this way, only one thread can enter the method of obtaining instances at the same time , Thread insecurity can be avoided !

shortcoming : Because it is locked , Only one thread can access this method at a time , Performance issues , Not recommended .

public static synchronized Singleton getUniqueInstance(){
    
        if (uniqueInstance == null){
    
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
Hungry Chinese style - Thread safety

It is also to solve the lazy thread insecurity problem , Just instantiate it directly , No longer use deferred instantiation , But no deferred instantiation saves resources

public class Singleton {
    

    private static Singleton uniqueInstance = new Singleton();

    private Singleton(){
    

    }

    public static synchronized Singleton getUniqueInstance(){
    
        return uniqueInstance;
    }
}
Double check lock - Thread safety

Just lock the instance , Do not lock the method

public class Singleton {
    

    private volatile static Singleton uniqueInstance;

    private Singleton(){
    

    }

    public static  Singleton getUniqueInstance(){
    
        if (uniqueInstance == null){
    
            synchronized (Singleton.class){
    
                if (uniqueInstance == null){
    
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

First explain why you use volatile keyword

prohibit jvm The command rearrangement of , There are three steps to instantiate an object

  1. Allocate memory space
  2. Initialize object
  3. Point the object to the allocated memory address

This order is in jvm The executor in may be out of order , For example 132 In this way , When a thread finishes executing 13 after , Another thread just entered if Judgment is not empty , An uninitialized object is returned directly , So in order to solve this problem, we use volatile Keyword can prevent instruction rearrangement

Explain why you use two if

When two threads enter the first one at the same time if, Both are judged not to be empty , Then lock it , A thread performs the operation of instantiating objects , After instantiation , Another thread also locks in , But if there is no second if Words , The second process will also be instantiated , After that, there will be no second instantiation .

Static inner class implementation - Thread safety

Is to use a static inner class , Class to write a static constant ,Singleton The inner class is not called when the class is loaded , Only when you need to get an instance, you can call the internal class to get it .

Implements deferred instantiation + Thread safety

public class Singleton {
    

    private Singleton(){
    

    }

    private static class SingletonHolder{
    
        private static final Singleton INSTANCE = new Singleton();
    }

    public static  Singleton getUniqueInstance(){
    
        return SingletonHolder.INSTANCE;
    }
}
原网站

版权声明
本文为[Program diary]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206252101115865.html