About the design mode of Singleton in Android Java

Source: Internet
Author: User

About the design mode of Singleton in Android Java

As code writing goes deeper, we will be more or less exposed to design patterns. Singleton should be a pattern we are familiar. This article will introduce the singleton mode in Java design patterns.

Concept

Singleton mode, also known as Singleton mode or Singleton mode, means that a class has only one instance and provides a global access point.

Implementation

  • Set a private static variable sInstance in the class of the singleton. The sInstance type is the current class, which is used to hold the unique instance of the Singleton.
  • The constructor is set to private to avoid using new to construct multiple instances externally.
  • Provides a public static method, such as getInstance, to return the unique sInstance of the class.

The preceding Singleton instance can be created in the following forms. Each implementation must ensure the uniqueness of the instance.

Hungry Chinese Style

Hunger refers to the creation of a single instance during class loading. If the construction method of the singleton class does not contain too many operations, the hunger style is acceptable.

Common Code of the hungry Chinese style is as follows. It is executed when the SingleInstance class is loaded.

 
 
  1. private static SingleInstance sInstance = new SingleInstance(); 

The unique instance is initialized, and then getInstance () returns sInstance directly.

 
 
  1. public class SingleInstance { 
  2.   private static SingleInstance sInstance = new SingleInstance(); 
  3.    
  4.   private SingleInstance() { 
  5.   } 
  6.    
  7.   public static SingleInstance getInstance() { 
  8.       return sInstance; 
  9.   } 

Hungry Chinese style problems

  • If the constructor has too many operations, loading the class will be slow and may cause performance problems.
  • If the hungry Chinese style is used, only the class is loaded, and there is no actual call, which will cause a waste of resources.

Lazy

Lazy refers to the creation of a singleton instance when it is used for the first time. In this case, the possible problems with the hunger style are avoided.

However, considering the concurrent operations of multiple threadsNoThe code below is simple.

 
 
  1. public class SingleInstance { 
  2.   private static SingleInstance sInstance; 
  3.   private SingleInstance() { 
  4.   } 
  5.    
  6.   public static SingleInstance getInstance() { 
  7.       if (null == sInstance) { 
  8.           sInstance = new SingleInstance(); 
  9.       } 
  10.       return sInstance; 
  11.   } 

The above code may create multiple instances when multiple threads call getInstance intensively. For example, when thread A enters the code block null = sInstance, and thread A does not create A complete instance, if thread B also enters the code block, it will inevitably generate two instances.

Synchronized modification method

Using synchrnozed to modify the getInstance method may be the simplest method to ensure the uniqueness of a single instance through multiple threads.
After the method modified by synchronized, when a thread calls this method, the thread enters this method only when other threads leave the current method. Therefore, it can be ensured that only one thread enters the getInstance at any time.

 
 
  1. public class SingleInstance { 
  2.   private static SingleInstance sInstance; 
  3.   private SingleInstance() { 
  4.   } 
  5.    
  6.   public static synchronized SingleInstance getInstance() { 
  7.       if (null == sInstance) { 
  8.           sInstance = new SingleInstance(); 
  9.       } 
  10.       return sInstance; 
  11.   } 

However, modifying the getInstance method with synchronized will inevitably lead to performance degradation, and getInstance is a frequently called method. Although this method can solve the problem, it is not recommended.

Double check and lock

Use double check and lock. First, the system performs the null = sInstance check when entering this method. If the first check passes, that is, no instance is created, the system enters the synchronization block controlled by synchronized, check whether the instance is created again. If not, create the instance.

Double check locking ensures that only one instance is created under multiple threads, and the lock code block is synchronized only before the instance is created. If you enter this method after the instance has been created, the code to the synchronization block will not be executed.

 
 
  1. public class SingleInstance { 
  2.   private static volatile SingleInstance sInstance; 
  3.   private SingleInstance() { 
  4.   } 
  5.    
  6.   public static SingleInstance getInstance() { 
  7.       if (null == sInstance) { 
  8.           synchronized (SingleInstance.class) { 
  9.               if (null == sInstance) { 
  10.                   sInstance = new SingleInstance(); 
  11.               } 
  12.           } 
  13.       } 
  14.       return sInstance; 
  15.   } 

What is volatile?

Volatile is a lightweight synchronized that ensures "visibility" of shared variables in multi-processor development ". Visibility means that when a thread modifies a shared variable, another thread can read the modified value. After modifying the sInstance variable using volatile, you can ensure that sInstance variables are correctly processed between multiple threads.
For more information about volatile, visit the in-depth analysis of the implementation principles of Volatile.

Static Mechanism

In Java, static initialization of a class is triggered when the class is loaded. We can use this principle to implement the following code by combining the internal class, to create an instance.

 
 
  1. public class SingleInstance { 
  2.   private SingleInstance() { 
  3.   } 
  4.    
  5.   public static SingleInstance getInstance() { 
  6.       return SingleInstanceHolder.sInstance; 
  7.   } 
  8.    
  9.   private static class SingleInstanceHolder { 
  10.       private static SingleInstance sInstance = new SingleInstance(); 
  11.   } 

For more information about this mechanism, see double check locking and delayed initialization.

Curious question

Is there really only one object?

In fact, the singleton mode does not guarantee the uniqueness of the instance. If we want to solve the problem, we can still break the uniqueness. The following methods can be implemented.

  • Using Reflection, although the constructor is not public, it does not work in front of reflection.
  • If the single-instance class implements cloneable, you can still copy multiple instances.
  • Serialization of objects in Java may also lead to the creation of multiple instances. Avoid using the readObject method.
  • Using multiple classloaders to load a singleton class also causes the coexistence of multiple instances.

Can a single instance be inherited?

Whether a singleton class can be inherited depends on the situation.

Inheritance allowed

When the subclass is an internal class of the parent class Singleton class, inheritance is acceptable.

 
 
  1. public class BaseSingleton { 
  2.   private static volatile BaseSingleton sInstance; 
  3.    
  4.   private BaseSingleton() { 
  5.        
  6.   } 
  7.    
  8.   public static BaseSingleton getInstance() { 
  9.       if (null == sInstance) { 
  10.           synchronized(BaseSingleton.class) { 
  11.               if (null == sInstance) { 
  12.                   sInstance = new BaseSingleton(); 
  13.               } 
  14.           } 
  15.       } 
  16.       return sInstance; 
  17.   } 
  18.    
  19.   public static class  MySingleton extends BaseSingleton { 
  20.        
  21.   } 
  22.    

However, the above is only allowed for compilation and execution, but inheriting a singleton has no practical significance. Instead, it will be even more difficult. The cost is higher than that of writing a new Singleton class. If you are interested, try again.

It cannot be inherited.

If the subclass is a separate class and it is not an internal class of the singleton class, an error will occur during compilation.Implicit super constructor BaseSingleton() is not visible for default constructor. Must define an explicit constructorThe main reason is that the constructor of the singleton class is private, and the solution is to set the constructor to visible, but this does not guarantee the uniqueness of the Singleton. Therefore, this method cannot be inherited.

In general, the singleton class should not be inherited.

 

Singleton vs static variable

 

Global static variables can also achieve the effect of Singleton, but the use of global variables cannot ensure that only one instance is created, and the use of global variables requires team constraints, problems may occur during execution.

GC

Because another static variable in the singleton class holds the singleton instance, compared with common objects, the objects in the singleton class are not easily recycled by GC. The recycling of Singleton objects should occur after the class loader is recycled by GC, which is generally not easy to appear.

Related Article

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.