Design Patterns (1) - Singleton Pattern

 

Singleton pattern is a commonly used software design pattern. In its core structure it contains only a special class called a singleton. The singleton pattern ensures that there is only one instance of a class in the system. That is, a class has only one object instance .

The common singleton pattern is written as follows:

//Only inner classes can be static.
public class Singleton{
    //Define an instance of yourself within yourself, only for internal calls  
       private static final Singleton instance = new Singleton ();
           private Singleton (){
               }
               //This provides a static method for external access to this class , you can directly access    
  public static Singleton getInstance(){  
         return instance;  
            } }

Advantages of Singleton Pattern

(1). Since the singleton pattern has only one instance in the memory, the memory overhead is reduced, especially when an object needs to be created and destroyed frequently, and the performance cannot be optimized when it is created or destroyed, the advantages of the singleton pattern are very obvious. . 

(2). Since the singleton mode only generates one instance, the performance overhead of the system is reduced. When the generation of an object requires more resources, such as reading the configuration and generating other dependent objects, you can start the application by starting the application. When a singleton object is directly generated, it is solved by permanently resident in memory. 

(3). The singleton mode can avoid multiple occupation of resources, such as a write file operation. Since only one instance exists in the memory, simultaneous write operations to the same resource file are avoided. 

(4). The singleton mode can set global access points in the system to optimize and share resource access. For example, a singleton class can be designed to be responsible for the mapping of all data tables.

 

Disadvantages of Singleton Pattern

 

(1). The singleton mode generally has no interface, and it is difficult to expand. If you want to expand, there is basically no second way to achieve it except modifying the code. 

(2). If the singleton object holds the Context, it is easy to cause memory leaks. At this time, it should be noted that the Context passed to the singleton object is preferably the Application Context.

 

Seven ways to write the singleton pattern

1. (lazy, thread-unsafe):

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

This way of writing does not work well in multithreading.

 

2. (lazy, thread safe):

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

This way of writing can work well in multi-threading, but it is very inefficient and does not require synchronization in 99% of cases.

 

3. (Hungry man):

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

Hungry-style has created a static object for the system to use when the class is created, and will not change it in the future, so it is inherently thread-safe. This way of writing can work well in multi-threading, but every time the getInstance method is called, it needs to be synchronized, causing unnecessary synchronization overhead, and most of the time we don't need synchronization.

 

4. Double Check Mode (DCL)

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

This writing method evaluates the singleton twice in the getSingleton method. The first time is for unnecessary synchronization, and the second time is to create an instance when the singleton is equal to null. The advantage of DCL is that the resource utilization is high, and the singleton object is instantiated when getInstance is executed for the first time, which is highly efficient. The disadvantage is that the response is slightly slower when it is loaded for the first time, and there is a possibility of failure.

 

5. Static inner class

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

When the Singleton class is loaded for the first time, sInstance is not initialized. Only when the getInstance method is called for the first time, the virtual machine loads the SingletonHolder and initializes sInstance, which not only ensures thread safety but also ensures the uniqueness of the Singleton class. A very reasonable singleton mode .

 

6. Enumeration

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

7. Use containers

public class SingletonManager {
   private static Map<String, Object> objMap = new HashMap<String,Object>();//Use HashMap as a cache container  
    private Singleton() {
       }  
public static void registerService(String key, Objectinstance) {
       if ( !objMap.containsKey(key) ) {
       objMap.put(key, instance) ;//The first time is stored in Map
           }
             }  
public static ObjectgetService(String key) {  
       return objMap.get(key) ;//Return and key the corresponding object
         } }

Use SingletonManager to manage a variety of singleton classes in a unified manner, and obtain objects of the corresponding type of objects according to the key when in use. When users use it, they only need to obtain the corresponding ServiceFetcher according to the key, and then obtain the specific service object through the getService function of the ServiceFetcher object. When it is fetched for the first time, it will call the creatService function of ServiceFetcher to create a service object, and then cache the object in a list, and get it directly from the cache when it is fetched next time, so as to avoid the repeated creation of objects, so as to achieve the effect of singleton. System core services in Android exist in the form of singletons, reducing resource consumption.

 

 

Summarize:

No matter what form the singleton pattern is implemented in, their core principle is to privatize the constructor and obtain a unique instance through static public methods. In the process of obtaining, thread safety must be ensured, and singletons must also be prevented. The resource consumption of the object.

 

My WeChat public account: Android dry goods shop

Focus on Android technology sharing, from start to advanced, insist on originality, carefully summarize the technical dry goods at each stage, including interviews, design pattern architecture, performance optimization, technical function realization, etc.; not only that, but also share some workplace experience and insights. Every month, we will strive to send books to everyone.

 

I set up an Android newcomer exchange group. If you are new to Android or plan to learn Android, you can add:

 Group number: 458739310

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326026848&siteId=291194637