Singleton mode is the most common and simplest design mode in design mode, ensuring that only one instance exists in the program and can be accessed globally. For example, the singleton mode is used in the management of account information object and database objects (SQLiteOpenHelper) used in the development of actual Android APPs. The following is analyzing the points we need to pay attention to when applying singleton mode during development.
1. Function
Singleton: Ensure that a class has only one instance and provides a global access point to access it.
2. Applicable scenarios
1. An instance object in the application needs to be accessed frequently.
2. There will be only one instance in each startup in the application. Such as account system, database system.
3. Commonly used methods
(1) Lazy style
This is a way that can be written easily in development, as follows
public class Singleton { /* Hold a private static instance to prevent reference. The value is assigned to null here, with the purpose of achieving lazy loading */ private static Singleton instance = null; /* Private constructor method to prevent instantiation */ private Singleton() { } /* 1: lazy, static engineering method, create instance */ public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
Called:
().method();
Advantages: Lazy loading (loading only when needed)
Disadvantages: Threads are unsafe, and it is easy to be out of synchronization in multithreads, such as when database objects perform frequent read and write operations.
(2) Add a synchronous lock
Since threads are not safe, add the synchronization lock, and an addition is as follows:
/*2. Lazy variant to solve thread safety problems**/ public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }
This is more general writing
/* Plus synchronized, but every time the instance is called, it will load **/ public static Singleton getInstance() { synchronized (Singletonclass) { if (instance == null) { instance = new Singleton(); } } return instance; }
Called:
().method();
Advantages: Solve the problem of thread insecure.
Disadvantages: The efficiency is a bit low, and the synchronization lock must be judged every time the instance is called.
Supplement: The singleton methods used in Android source code are: InputMethodManager, AccessibilityManager, etc., all use this singleton mode.
(3) Double inspection lock
To optimize (2), because every time an instance is called, many people use the following double judgment verification method
/*3.Double lock: Only add synchronization locks during the first initialization*/ public static Singleton getInstance() { if (instance == null) { synchronized (Singletonclass) { if (instance == null) { instance = new Singleton(); } } } return instance; }
This method seems to solve the above efficiency problem perfectly. It may run perfectly in situations where there is not much concurrency and low security, but there are also unfortunate aspects of this method. The problem appears in this sentence
instance = new Singleton();
During the JVM compilation process, the instruction reordering optimization process will occur, which will cause the memory space to be allocated when the instance has not been initialized, which means that the instance !=null but it is not initialized, which will cause the returned instance to be incomplete.
Called:
().method();
Advantages: In the case of insufficient concurrency and low security, singleton mode may be able to run perfectly
Disadvantages: There may be serious security risks during the compilation process of different platforms.
Supplement: This is used in the Android-Universal-Image-Loader open source project.
(4) Implementation of internal classes
Internal classes are a good implementation method, and you can recommend using the following:
public class SingletonInner { /** * Inner class implements singleton mode * Lazy loading, reducing memory overhead * * @author xuzhaohu * */ private static class SingletonHolder { private static SingletonInner instance = new SingletonInner(); } /** * Private constructor */ private SingletonInner() { } public static SingletonInner getInstance() { return SingletonHolderinstance; } protected void method() { Systemoutprintln("SingletonInner"); } }
Called:
().method();
Advantages: Lazy loading, thread-safe (mutually exclusive when loading in Java), and also reduces memory consumption
(5) Enumeration method
This is a practice recommended by many people on the Internet, but it seems that it is not widely used, so you can try it.
/** * @function: Singleton pattern enumeration implementation * @author xuzhaohu * */ public enum SingletonEnum { /** *Supported from Java5; * Provide serialization mechanism free of charge; * Absolutely prevent multiple instantiation, even when facing complex serialization or reflection attacks; */ instance; private String others; SingletonEnum() { } public void method() { Systemoutprintln("SingletonEnum"); } public String getOthers() { return others; } public void setOthers(String others) { thisothers = others; } }
Called:
();
Advantages and disadvantages: such as comments in the code.
The above mainly talks about five ways to create a singleton pattern. You can use it in your personal projects based on their advantages and disadvantages. What I said is about throwing bricks and attracting jade, so everyone will give me more opinions.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.