The outline

  • The hungry mode
  • Lazy mode (thread unsafe)
  • Lazy mode (thread-safe)
  • Double check mode
  • Static inner class singleton pattern
  • Enumeration mode
  • Deserialization causes the object to be recreated

1. Hungry

  • The instantiation is done when the class is loaded, avoiding multi-threaded synchronization issues, but not lazy loading
  • Not using this instance from start to finish results in a waste of memory

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

    private Singleton(a) {}private static Singleton getInstance(a) {
        returninstance; }}Copy the code

2. Lazy mode (thread unsafe)

Instantiating objects on first load does not work well with multithreading

public class Singleton {
    private static Singleton instance;

    private Singleton(a) {}public static Singleton getInstance(a) {
        if (instance == null) {
            instance = new Singleton();
        }
        returninstance; }}Copy the code

3. Slacker mode (thread-safe)

For multithreading, each call to getInstance requires synchronization, but incurs synchronization overhead


public class Singleton {
    private static Singleton instance;

    private Singleton(a) {}public static synchronized Singleton getInstance(a) {
        if (instance == null) {
            instance = new Singleton();
        }
        returninstance; }}Copy the code

4. Double check mode (DSL)

  • The first time for unnecessary synchronization operation, the second time when singleton is equal to null to create the instance, resource utilization is high
  • The use of volatile has a performance impact
  • There are pitfalls in the case of high concurrency, and DSLS fail. Static inner class singletons are recommended instead of DCLS

public class Singleton {
    private volatile static Singleton instance;

    private Singleton(a) {}public static Singleton getInstance(a) {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = newSingleton(); }}}returninstance; }}Copy the code

5. Static inner class singleton pattern

Loading the Singleton class for the first time will not be initialized, only the first load SingletonHolder. SInstance method when the virtual machine will load SingletonHodler and initialization, can not only guarantee thread safety, and can guarantee the uniqueness of the Singleton class


public class Singleton {
    private Singleton(a) {}public static Singleton getInstance(a) {
        return SingletonHolder.sInstance;
    }

    private static class SingletonHolder {
        private static final Singleton sInstance = newSingleton(); }}Copy the code

6. Enumerate singletons

The creation of enumeration singletons is thread-safe and singletons in all cases

enum Singleton {
    SINGLETON;

    public void doSomething(a) {}}Copy the code

7. Deserialization issues

The deserialization operation provides the readResolve method, which controls deserialization of objects

  1. No arguments 2. Return a method of type Object 3. Return a reference to a singleton instance

In the ObjectStraeamClass source code, this object will be created with or without the readResolve method, simply reassigning the address pointed to in memory to the reference to be returned

class Singleton implements Serializable {

    private Object readResolve(a) throws ObjectStreamException {
        returninstance; }}Copy the code