Design pattern (5) - seven kinds of single-mode implementation embodiment

Definition: to ensure only one instance of a class, and it provides access to a global access point.

Singleton pattern configuration diagram:

Write pictures described here

Singleton has written a variety of advantages and disadvantages, and now we take a look at the various modes of writing.

1. starving mode

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

In this way the class is loaded when the initialization is complete, the class loading is slow, but quickly get the object's speed. In this way based on class loading mechanism avoids the synchronization of multiple threads, but can not be sure there are other ways (or other static methods) leads the class loader, this time to initialize instance apparently did not achieve the effect of lazy loaded.

2. Lazy mode (thread safe)

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

Lazy mode declare a static object, initialized when a user first call, while saving resources, but need to be instantiated when you first load, reflecting slightly slower, but does not work in a multi-threaded.

3. Lazy mode (thread-safe)

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

Such an approach can work well in multi-thread, but need to be synchronized every time getInstance method is called, causing unnecessary synchronization overhead, and most of the time we are less than synchronized, so I do not recommend this mode.

4. Double check mode (DCL)

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

The wording in getSingleton method of singleton was twice sentenced to air for the first time for unnecessary synchronization, the second was only to create an instance in the case of singleton equal to null. In the volatile keyword is used here, you can not understand their own network volatile keyword search query; used here will be more or less volatile performance impact, but considering the correctness of the program, the performance of this sacrifice is worth it. DCL advantage of high resource utilization, was only singleton object is instantiated when the getInstance first performance, high efficiency. The disadvantage is that when you first load slightly slower reaction in a highly concurrent environment also has some shortcomings, although the probability of occurrence is very small. DCL although to some extent solve the consumption of resources and redundant synchronization, thread-safety and other issues, but he still questions the failure occurs in some cases, DCL is invalid, the "java Concurrency in Practice," a book recommended by static internal class singleton pattern instead of DCL.

The static inner class Singleton

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

SInstance not initialized when you first load Singleton class, virtual machine load SingletonHolder only the first call to getInstance method and initialize sInstance, so not only can guarantee thread safety but also to ensure the uniqueness of Singleton class, it is recommended to use a static inner classes singleton .

6. enumeration singleton

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

Call the method:

public class Main {

    public static void main(String[] args) {
        Singleton.INSTANCE.doSomething();
    }

}

Create a default enumerate instances are thread-safe, and single cases are, in any case, several Singleton pattern to achieve the above talk, there one case that they will re-create the object, that is, deserialize, a the singleton instance of the object back to disk read, thereby obtaining an example. Deserialization operation provides readResolve method that allows the developer to control object deserialization. To eliminate the singleton object is deserialized object regenerated several methods example described above, it must be added as follows:

private Object readResolve() throws ObjectStreamException{
return singleton;
}

Enumerate the advantages of a single case is simple, but most application developers rarely use enumeration, readability is not very high, not recommended.

Finally borrow "Effective Java" book, then,

Single-element enumerated type has become the best way to achieve the Singleton.

Example 7. Use of the container for single mode

public class SingletonManager { 
  private static Map<String, Object> objMap = new HashMap<String,Object>();
  private Singleton() { 
  }
  public static void registerService(String key, Objectinstance) {
    if (!objMap.containsKey(key) ) {
      objMap.put(key, instance) ;
    }
  }
  public static ObjectgetService(String key) {
    return objMap.get(key) ;
  }
}

SingletonManager with the more unified management singleton class, when using the object type corresponding to the object according to the acquired key. Such a way that we can manage various types of a single embodiment, may be acquired and used when operating through a unified interface to reduce user costs, but also the realization of hidden from the user, reducing the degree of coupling.

to sum up

Here are seven of the written introduction is over, as to what form a single-case model of choice, depending on your project itself, whether there is a complex concurrent environment, need to control the singleton object or resource consumption.

Published 295 original articles · won praise 37 · views 30000 +

Guess you like

Origin blog.csdn.net/tianshan2010/article/details/104706100