当前位置:网站首页>Hand tearing algorithm - handwritten singleton mode

Hand tearing algorithm - handwritten singleton mode

2020-11-07 20:58:00 JaneRoad

## Why is there a singleton pattern

In the actual programming application scenario , There are some objects that we just need , For example, thread pool object 、 cache 、 System global configuration objects, etc . This ensures that a class used globally is not frequently created and destroyed , Save system resources .

## Several key points of implementing singleton pattern

### Be careful : 1、 A singleton class can have only one instance . 2、 The singleton class must create its own unique instance . 3、 The singleton class must provide this instance to all other objects .

Intention : Make sure there is only one instance of a class , And provide a global access point to access it . Main solution : A globally used class is frequently created and destroyed . When to use : When you want to control the number of instances , When saving system resources . How to solve : Judge whether the system has this single example , Return if any , If not, create . Key code : Constructor is private . ### Application example : 1、 There is only one head teacher in a class . 2、Windows It's multiprocess and multithreaded , When operating a file , It is inevitable that multiple processes or threads operate on a file at the same time , So all files must be processed through a unique instance . 3、 Some device managers are often designed as singleton , For example, a computer has two printers , When outputting, we have to deal with the problem that two printers can't print the same file . ### advantage : 1、 There is only one instance in memory , Reduced memory overhead , In particular, instances are created and destroyed frequently ( For example, cache the homepage of Management College ). 2、 Avoid multiple USES of resources ( Like writing a file ). shortcoming : No interface , Cannot inherit , Conflict with single responsibility principle , A class should only care about internal logic , But I don't care how to instantiate it outside . ### Use scenarios : 1、 Production unique serial number is required . 2、WEB The counter in , You don't need to add to the database every time you refresh , Cache it first with a singleton . 3、 An object created consumes too many resources , such as I/O Connection with database, etc . matters needing attention :getInstance() Method requires the use of a synchronous lock synchronized (Singleton.class) Prevent multiple threads from entering at the same time instance Instantiated multiple times .

#### step 1 Create a Singleton class . SingleObject.java

public class SingleObject {
   // establish  SingleObject  An object of 
   private static SingleObject instance = new SingleObject();
   // Let the constructor be  private, In this way, the class will not be instantiated 
   private SingleObject(){}
   // Get the only available object 
   public static SingleObject getInstance(){
      return instance;
   }
   public void showMessage(){
      System.out.println("Hello World!");
   }
}

#### step 2 from singleton Class gets the unique object . SingletonPatternDemo.java

public class SingletonPatternDemo {
   public static void main(String[] args) {

 // Illegal constructor 
      // Compile time error : Constructors  SingleObject()  It's invisible 
      //SingleObject object = new SingleObject();

  // Get the only available object 
      SingleObject object = SingleObject.getInstance();

// display messages 
      object.showMessage();

   }
}

#### step 3 Execution procedure , Output results : Hello World!

### Several ways to implement singleton pattern There are many ways to implement the singleton pattern , As shown below : ####1、 Slacker type , Thread unsafe

  • whether Lazy initialization : yes
  • Is multithreading safe : no
  • Difficulty of realization : easy

describe : This is the most basic way to achieve , The biggest problem with this implementation is that it doesn't support multithreading . Because there is no lock synchronized, So strictly speaking, it's not a singleton pattern . This way, lazy loading Obviously , Thread safety is not required , Multithreading doesn't work .

example

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}

The following several implementation methods all support multithreading , But there are differences in performance .

####2、 Slacker type , Thread safety

  • whether Lazy initialization : yes
  • Is multithreading safe : yes
  • Difficulty of realization : easy

describe : This way has a good lazy loading, Can work well in multithreading , however , Efficiency is very low ,99% There is no need to synchronize . advantage : The first call initializes , Avoid memory waste . shortcoming : Must be locked. synchronized To guarantee the single case , But locking can affect efficiency . getInstance() Performance is not critical for applications ( This method is not used frequently ). example

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static synchronized Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}

3、 Hungry Chinese style

  • whether Lazy initialization : no
  • Is multithreading safe : yes
  • Difficulty of realization : easy

describe : This way is more commonly used , But it is easy to produce garbage objects . advantage : No locks , The efficiency of execution will improve . shortcoming : Class is initialized when it is loaded , Waste of memory . It's based on classloader The mechanism avoids the synchronization problem of multithreading , however ,instance Instantiate at class load time , Although there are many reasons for class loading , In singleton mode, most of them call getInstance Method , But I'm not sure there are other ways ( Or other static methods ) Causes the class to load , This time initialization instance Obviously not lazy loading The effect of .

example

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}

####4、 Double check lock / Double check lock (DCL, namely double-checked locking)

  • JDK edition :JDK1.5 rise
  • whether Lazy initialization : yes
  • Is multithreading safe : yes
  • Difficulty of realization : More complicated

describe : This method adopts double lock mechanism , It is safe and can maintain high performance in multithreading .getInstance() Performance is critical to the application .

example

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton(); 
        }  
        }  
    }  
    return singleton;  
    }  
}

####5、 Registration form / Static inner class

  • whether Lazy initialization : yes
  • Is multithreading safe : yes
  • Difficulty of realization : commonly

describe : This way can achieve the same effect of double lock , But it's easier to achieve . Use delay initialization for static fields , This method should be used instead of double locking . This method only applies to the static domain , The double check lock mode can be used when the instance domain needs to delay initialization . This approach also takes advantage of classloader Mechanism to ensure initialization instance There is only one thread , It follows the 3 The difference is : The first 3 There's only one way Singleton Class is loaded , that instance It will be instantiated ( Don't reach lazy loading effect ), And this way is Singleton Class is loaded ,instance Not necessarily initialized . because SingletonHolder Class is not actively used , Only by explicitly calling getInstance When the method is used , To explicitly load SingletonHolder class , To instantiate instance. Imagine , If you instantiate instance It's a drain on resources , So I want it to delay loading , On the other hand , I don't want to be in Singleton The class is instantiated when it is loaded , Because there's no guarantee Singleton Classes may also be actively used elsewhere to be loaded , So this is the time to instantiate instance Clearly not appropriate . This is the time , This way is better than 3 That's a reasonable way .

example

public class Singleton {  
    private static class SingletonHolder {  
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
    return SingletonHolder.INSTANCE;  
    }  
}

####6、 enumeration

  • JDK edition :JDK1.5 rise
  • whether Lazy initialization : no
  • Is multithreading safe : yes
  • Difficulty of realization : easy

describe : This implementation has not been widely adopted , But this is the best way to implement the singleton pattern . It's simpler , Automatic support for serialization mechanism , Absolutely prevent multiple instantiations . This way is Effective Java author Josh Bloch Ways to advocate , It not only avoids the multithreaded synchronization problem , It also automatically supports serialization mechanism , Prevents deserialization from recreating new objects , Absolutely prevent multiple instantiations . however , because JDK1.5 After that enum characteristic , It feels strange to write in this way , In practice , Rarely use . Cannot pass reflection attack To call the private constructor .

example

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}

Wise remark of an experienced person : In general , It is not recommended to use 1 Species and 2 A lazy way , It is recommended to use section 3 The way of starving people . Only if we want to realize lazy loading In effect , Will use the 5 How to register . If it comes to deserialization when creating objects , You can try using section 6 There are several ways to enumerate . If there are other special needs , Consider using section 4 Double lock mode .

版权声明
本文为[JaneRoad]所创,转载请带上原文链接,感谢