Four implementations of Android singleton pattern

  • 2021-12-12 09:58:16
  • OfStack

Catalogue 1. Hungry Han Style 2. Lazy Han Style 3. Double check and lock mode 4. Static inner class mode summary

1. Hungry Han style


public class SingletionStarving {

    private static final SingletionStarving mInstance = new SingletionStarving();

    private SingletionStarving() {

    }

    public static SingletionStarving getInstance() {
        return mInstance;
    }
}
The constructor is decorated with private and cannot be accessed externally Class when a static object is declared static keyword modification, static variable, stored in memory, only 1 data. final keyword, initialized only once, so there is only one mInstance instance.

2. Lazy style


public class SingletionSlacker {

    private static SingletionSlacker mInstance;

    private  SingletionSlacker() {}

    public static synchronized SingletionSlacker getInstance() {
        if (mInstance == null) {
            mInstance = new SingletionSlacker();
        }
        return mInstance;
    }
}
Constructor decorated with private, externally inaccessible Initialized when used, that is, when calling getInstance static keyword modification, static variable, stored in memory, only 1 data. synchronized Thread Safety, Uniqueness of Single Instance in Multithreaded Condition Disadvantages: getInstance will be synchronized once every time it is called, which wastes resources

3. Double check locking method

The most suggested and used methods on the Internet


public class Singletion {

    private static Singletion mInstance;

    private Singletion() {}

    public static Singletion getmInstance() {
        if (mInstance == null) {
            synchronized (Singletion.class) {                if (mInstance == null) {
                    mInstance = new Singletion ();                }
            }
        }
        return mInstance;
    }
}
Constructor is decorated with private and cannot be accessed externally Initialized when used, that is, when calling getInstance static keyword modification, static variable, stored in memory, only 1 data synchronized Thread Safety, Uniqueness of Single Instance in Multithreaded Condition Determine null twice to avoid multiple synchronizations (synchronized)

Disadvantages


private static Singletion mInstance;
private Singletion() {}
public static Singletion getmInstance() {}

Due to the characteristics of jvm, out-of-order execution is allowed, and the order of the above three sentences of code is uncertain, so the problem of failure may occur.
Step 1. If the A thread executes getmInstance (), the constructor Singletion () has not been executed
Step 2. At this point, the B thread calls getmInstance (). Because A already executes getmInstance (), mInstance is fetched without being empty.
Step 3. mInstance is empty because B is fetched directly and the reality is that the A thread constructor has not been executed.
Although the probability of this situation is small, it is also a situation. To address this situation, java 1.6 began adding the volatile keyword


private volatile static Singletion mInstance;

In this way, the failure of the mode is avoided. Although volatile consumes 1% performance, the best way to write it is


public class Singletion {

    private volatile static Singletion mInstance;
    private Singletion () {}
    public static Singletion getmInstance() {        if (mInstance == null) {
            synchronized (Singletion.class) {                if (mInstance == null) {
                    mInstance = new Singletion();                }
            }
        }
        return mInstance;
    }
}

Although volatile makes the way perfect, no volatile keyword can basically meet most situations. Unless you want to run in high concurrency or code before java 1.6.

4. Static inner class mode


public class SingletionInternalClass {

    private SingletionInternalClass() {}

    public static SingletionInternalClass getInstance() {
        return SingletionInternalClassHolder.instance;
    }

    private static class SingletionInternalClassHolder {
        private static final SingletionInternalClass instance = new SingletionInternalClass();
    }
}

Constructor is decorated with private and cannot be accessed externally

Initialized when used, that is, when calling getInstance

The SingletionInternalClassHolder class is loaded only after calling getInstance, which ensures thread safety and uniqueness of singleton

Summarize

No matter how the singleton pattern is implemented, the core idea is the same
1. The constructor is privatized, and one only instance is obtained by one static method
2. Thread safety

Finally, it is recommended to create singleton patterns using the * * double locking method and the static inner class method * * in this paper.

The above is the Android singleton mode of the 4 implementation details, more information about the implementation of the Android singleton mode please pay attention to other related articles on this site!


Related articles: