Seven ways to approach the single-instance mode of Android design mode

Source: Internet
Author: User

An introduction to a single case pattern and its usage scenarios

The singleton pattern is the most widely used mode and one of the first design patterns I know. Before you dive into the singleton pattern. Whenever I encounter code that creates an instance like: getinstance (), I think of it as a single implementation of a singleton pattern.

The fact that often used images loaded into the framework Imageloader instance creation is the use of singleton mode. Because this imageloader contains thread pools, cache systems, network requests, and consumes resources, you should not create multiple objects, and you need to use a singleton mode.

The creation code for Imageloader is as follows:

Imageloader.getinstance ();//Create a global instance in your own application.....//getinstance () run the source code  Public StaticImageloadergetinstance() {if(Instance = =NULL) {//double-check DCL single-case modeClass var0 = Imageloader.class;synchronized(Imageloader.class) {//Synchronous code block                if(Instance = =NULL) {instance =NewImageloader ();//Create a new instance}            }        }returnInstance//Returns an instance}

Therefore, when we create an object that consumes too much resources. You can consider using singleton mode.

The structure diagram of the two singleton patterns and the key points of the creation?

The singleton pattern is defined as it should guarantee that there is only one instance of a class, and at the same time the class must provide a global access point to the class. For example, a structure diagram with a singleton pattern:

There are several key points to implementing the Singleton pattern:
(1) Its construction function is not correct outside the open, generally private;
(2) Returning a singleton class object through a static method or enumeration;
(3) Ensure that the object of the Singleton class has only one, especially to pay attention to the multi-threading scenario.
(4) Ensure that the Singleton class object does not create the object again when deserializing;

By privatizing the constructor of a singleton class, the client cannot manually construct an object of the Singleton class by using new form. A singleton class will proactively expose a public static method. The client calls this static method to get the unique instance of the Singleton class. It is necessary to ensure that the process is thread-safe when getting this singleton class.

Seven implementations of the three single-instance modes (1) lazy (thread insecure)
//lazy Type singleton class. Instantiate yourself   class  Singleton {//private constructors   private  singleton  () {} // private static variable  private  static  Singleton Single =null ; //exposed public static method  public  static  Singleton getinstance  () {if  (single = null ) {single = new  Singleton (); } return  single; } }

The lazy (thread insecure) singleton pattern is divided into three parts: a private constructor, a private global static variable. The public static method.

One of the most important things is the static modifier statics keyword, and we know that in a program, whatever variable or code is stored by the system's own active allocation of memory at compile time, the so-called static means that the memory allocated after compilation will persist. This space is not freed until the program exits memory. As a result, instances of singleton classes are not reclaimed by the system once they are created, unless they are manually set to NULL.

The disadvantage of this approach is that there is a thread insecurity, and the solution is to use the Synchronized keyword, which is another way of writing a singleton pattern.

(2) Lazy (thread-safe)
publicclass Singleton {      //私有的静态变量    privatestatic Singleton instance;      //私有的构造方法    privateSingleton (){};    //公有的同步静态方法    publicstaticgetInstance() {      ifnull) {          new Singleton();      }      return instance;      }  }  

The getinstance () method of such a singleton implementation adds the Synchronized keyword, which tells the Java (JVM) getinstance to be a synchronous method.

Synchronization means that when two concurrent threads visit this synchronized synchronization method in the same class, only one thread can be run within a single time, and one thread must wait for the current thread to run, so the synchronization method makes thread safe, ensuring that only one instance of the singleton is available.

However, its disadvantage is that each call to getinstance () is synchronized, resulting in unnecessary synchronization overhead. Such a pattern is generally not recommended for use.

(3) A Hungry man mode (thread safe)

Code implementations such as the following:

//饿汉式单例类.在类初始化时,已经自行实例化   publicclass Singleton {      //static修饰的静态变量在内存中一旦创建,便永久存在    privatestaticnew Singleton();      privateSingleton (){}      publicstaticgetInstance() {      return instance;      }  

A hungry man the same time that the class was created, a static object was created for the system to use. It doesn't change anymore, so it's inherently thread-safe. Among them Instance=new Singleton () can be written as:

static {      new Singleton();      }  

A hungry man is a variant of the single-case pattern, but also based on the classloder mechanism to avoid multi-threaded synchronization problems, instance in class loading is instantiated.

(4) DCL double check mode
 Public classSingleton {Private StaticSingleton Singleton;//static variable    Private Singleton(){}//Private Constructors     Public StaticSingletongetinstance() {if(Singleton = =NULL) {//First level checkSynchronized (Singleton.class) {if(Singleton = =NULL) {//second level checkSingleton =NewSingleton (); }          }        }returnSingleton }  }

The highlight of this pattern is the getinstance () method, in which the singleton is inferred to be null two times, and the first layer is inferred to avoid unnecessary synchronization. The second-level inference is to create an instance in the case of NULL. For more details, let's analyze:

If thread a runs to Singleton = new Singleton (); statement, which looks like a code, but it is not an atomic operation, this code will eventually be compiled into multiple assembly instructions, which will roughly do three things:
(a) Allocating memory to instances of Singleton
(b) Call the constructor of Singleton () to initialize the member field.
(c) Point the Singleton object to the allocated memory space (that is, Singleton is not empty);

However, because the Java compiler agrees that the processor runs in a disorderly sequence. And before jdk1.5, the JMM (Java memory Model:java memory model) cache, register, to main memory write-back order, the above step b step c is not guaranteed to run the order. This means that the order of operation may be a-b-c. It may also be a-c-b, if it is the latter's point order, and exactly in C run is done. b is switched to thread B when it is not already running. At this time, because Singleton is running step c in thread A, it is not empty. So. Thread B takes the singleton directly and then makes an error when it is used.

This is the problem of the DCL failure.
After JDK1.5, however, the official gave the volatile keyword, changing the code defined by singleton to:

privatevolatilestatic Singleton singleton;  //使用volatile 关键字

This overcomes the problem of the DCL failure.

(5) Static internal class Singleton mode
public   Class  Singleton {private  singleton  () {}; Span class= "Hljs-comment" >//private constructor  public   Static  final Singleton getinstance  () {return
      singletonholder.instance; } //defined static inner class  private  static  class  singletonholder {private static  final Singleton INSTANCE = new   Singleton ();  //the place where the instance was created } }  

When loading the Singleton class for the first time, the instance is not initialized and only the getinstance () method of the first call to Singleton causes the instance to be initialized. Therefore, the first call to the getinstance () method causes the virtual airborne into the Singletonholder class, which not only ensures uniqueness of the Singleton object, but also delays the instantiation of the Singleton.

(6) enumeration of single cases

Several of the previous singleton patterns are implemented in a slightly cumbersome way, or in certain situations. The following describes the implementation of the enumeration singleton pattern:

publicenum Singleton {  //enum枚举类    INSTANCE;      publicvoidwhateverMethod() {      }  }

The best advantage of enumerating the singleton patterns is that they are simple to do, and enumerations are the same in Java as normal classes. Not only can you have fields, but you can also have your own methods, and most importantly, the default enumeration instances are thread-safe, and in whatever circumstances. It's all a single case. Even in the process of deserialization. An enumeration singleton also does not generate new instances again. and several other ways. You must include methods such as the following:

privatereadResolve()  throws ObjectStreamException{    return INSTANCE;}

Ability to ensure that no new objects are generated when deserializing.

(7) Using a container to implement a singleton mode

In addition to the several common ways to implement a singleton, there is a class of implementations, such as the following code:

 Public classSingletonmanager {Private Staticmap<string, object> objmap =NewHashmap<string,object> ();//using HashMap as the cache container    Private Singleton() {   } Public Static void Registerservice(String key, ObjectInstance) {if(!objmap.containskey (key)) {Objmap.put (key, instance);//The first time is to deposit a map}  } Public Static Objectgetservice(String key) {returnObjmap.Get(key);//Returns the object corresponding to key}}

At the beginning of the program. Inject a variety of singleton patterns into a unified management class and get the corresponding type of objects by key when used.

In the Android source code. When the app starts. The first time a virtual machine loads the class, it will register various servicefetcher, such as the Layoutinflater Service. Store these services in a hashmap in the form of key-value pairs. Users only need to rely on key to obtain the corresponding servicefetcher. The detailed service object is then obtained through the GetService function of the Servicefetcher object. When the first time is acquired. The Servicefetcher Creatservice function is called to create the service object. The object is then cached in a list. The next time it is fetched directly from the cache, avoid repeatedly creating objects, so as to achieve the effect of a singleton. System core Services in Android exist in a single case, reducing resource consumption.

Summary: The singleton mode is implemented regardless of the form. Their core principle is to privatize the constructor and obtain a unique instance through a static public method. Thread security must be ensured during this acquisition. Also prevent deserialization at the same time from causing the instance object to be generated again.

Seven ways to approach the single-instance mode of Android design mode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.