Design mode (02) singleton mode

1. Interpretation of single case mode

1.1 introduction to singleton mode

@1. Single case mode

It belongs to the creation mode, which involves a single class, which is responsible for creating its own objects and ensuring that only a single object is created. This class provides a way to access its unique object, which can be accessed directly without instantiating the object of this class. The characteristics of single case are:

  • There can only be one instance.
  • You must create your own unique instance and the} constructor is private.
  • This instance must be provided to all other objects.

@2 5W1H# model interpretation single case mode

  • The purpose of why singleton pattern is to ensure that a class has only one instance and provide a global access point to access it. The main usage scenarios are:
    • There is only one head teacher in a class. No matter how many students need support, it's her / him.
    • When operating a file under windows # operating system, it is inevitable that multiple processes or threads operate a file at the same time, so all files must be processed through a unique instance.
    • Some device managers are often designed in singleton mode. For example, a computer has two printers, which must be processed when outputting. Two printers cannot print the same file.
    • The counters in the WEB do not need to be added to the database every time they are refreshed, but are cached first with a single instance.
    • Creating an object consumes too many resources, such as the connection between I/O and database.
  • what mainly solves: a globally used class is frequently created and destroyed.
  • when/where: when/where you want to control the number of instances and save system resources.
  • how to solve: judge whether the system already has this single instance. If so, return it. If not, create it.

@3 advantages and disadvantages of singleton mode

  • Advantages: there is only one instance in memory, which reduces memory overhead, especially frequent creation and destruction of instances; And avoid multiple occupation of resources (such as writing files).
  • Disadvantages: there is no interface and cannot be inherited, which conflicts with the principle of single responsibility. A class should only care about the internal logic rather than how to instantiate it outside.

@4. UML diagram of singleton pattern

1.2 simple implementation of singleton mode (Java)

The implementation of Singleton class in Singleton mode is as follows:

public class SingleObject {
 
   //Create an object of SingleObject
   private static SingleObject instance = new SingleObject();
 
   //If the constructor is private, the class will not be instantiated
   private SingleObject(){}
 
   //Gets the only available object
   public static SingleObject getInstance(){
      return instance;
   }
 
   public void showMessage(){
      System.out.println("show message: SingleObject mode");
   }
}

Test the class and use the singleton class to get the unique object. The implementation is as follows:

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

      //Gets the only available object
      SingleObject object = SingleObject.getInstance();
 
      //display messages
      object.showMessage();
   }
}

2. Implementation mode of singleton mode

2.1. Lazy, thread unsafe

Description:

  • Whether to initialize Lazy: Yes
  • Multithread safe: no
  • Implementation difficulty: easy

Advantages and disadvantages:

  • Advantages: simple implementation
  • Disadvantages: multithreading is not supported

realization:

public class Singleton {  
    private static Singleton instance;  

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

2.2. Lazy, thread safe

Description:

  • Whether to initialize Lazy: Yes
  • Multithread safe: Yes
  • Implementation difficulty: easy

Advantages and disadvantages:

  • Advantages: initialize only after the first call to avoid memory waste.
  • Disadvantages: you must lock synchronized to ensure single instance, but locking will affect efficiency.

realization:

public class Singleton {  
    private static Singleton instance;  

    private Singleton (){}  

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

2.3 hungry Han style

Description:

  • Lazy initialization: no
  • Multithread safe: Yes
  • Implementation difficulty: easy

Advantages and disadvantages:

  • Advantages: without locking, the execution efficiency will be improved. At the same time, # based on the classloader mechanism, the synchronization problem of multithreading is avoided.
  • Disadvantages: class initialization when loading, wasting memory. Prone to garbage objects.

realization:

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

    private Singleton (){}  

    public static Singleton getInstance() {  
        return instance;  
    }  
}

2.4. Double checked locking (DCL)

Description:

  • Whether to initialize Lazy: Yes
  • Multithread safe: Yes
  • Implementation difficulty: relatively complex

Advantages and disadvantages:

  • Advantages: this method adopts double lock mechanism, which is safe and can maintain high performance in the case of multithreading
  • Disadvantages: cumbersome implementation.

realization:

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;  
    }   
}

2.5 registered / static internal class

Description:

  • Whether to initialize Lazy: Yes
  • Multithread safe: Yes
  • Implementation difficulty: General

Advantages and disadvantages:

  • Advantages: it can achieve the same effect as the double check lock mode, but the implementation is simpler. When using delayed initialization for static domains, this method should be used instead of double check locking.
  • Disadvantages: it is only applicable to the static domain. The double check lock mode can be used when the instance domain needs to delay initialization.

realization:

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

Special note: this method also uses the classloader mechanism to ensure that there is only one thread when initializing the instance. It is different from the method in 2.3: in 2.3, as long as the Singleton class is loaded, the instance will be instantiated (without the lazy loading effect). This method is that the Singleton class is loaded, and the instance is not necessarily initialized. Because the SingletonHolder class is not actively used, the SingletonHolder class will be explicitly loaded to instantiate the instance only when the getInstance method is explicitly called. Imagine if instantiating an instance consumes a lot of resources, so you want it to delay loading. On the other hand, you don't want to instantiate it when the Singleton class is loaded, because you can't ensure that the Singleton class may be actively used in other places and loaded, so instantiating an instance at this time is obviously inappropriate. At this time, this method is very reasonable compared with the method in 2.3.

2.6 enumeration

Description:

  • Lazy initialization: no
  • Multithread safe: Yes
  • Implementation difficulty: easy

Advantages and disadvantages:

  • Advantages: this implementation method is more concise, automatically supports serialization mechanism, and absolutely prevents multiple instantiations. This method is also advocated by Effective Java author Josh Bloch. It can not only avoid the problem of multi-threaded synchronization, but also automatically support the serialization mechanism to prevent deserialization, re create new objects, and absolutely prevent multiple instantiations.
  • Disadvantages: however, due to jdk1 The enum feature was added after 5. It feels strange to write in this way, and it is rarely used in practical work. Although not widely adopted, this is the best way to implement singleton mode. At the same time, {you cannot call a private constructor through reflection attack.

realization:

public enum Singleton {  
    INSTANCE;  
    public void dosomething() {
        System.out.println("do something");
    }  
}

 

Added by mouloud2001 on Thu, 10 Feb 2022 04:27:09 +0200