Singleton pattern of design patterns you can understand

preface

*** The author writes a blog mainly to summarize the technology and deepen his understanding of it. If there are any mistakes, please help point out them.

Singleton mode

1. Definitions

Definition of Singleton pattern: a pattern in which a class has only one instance and the class can create the instance itself.

2. Features

  1. A singleton class has only one instance object;
  2. The singleton object must be created by the singleton class itself;
  3. The singleton class provides a global access point for accessing the singleton.

3. Advantages and disadvantages

advantage:

  1. Singleton mode can ensure that there is only one instance in memory and reduce the memory overhead.
  2. Multiple occupation of resources can be avoided.
  3. The global access point is set in the singleton mode, which can optimize and share the access of resources.

Disadvantages:

  1. Singleton mode generally has no interface and is difficult to expand.
  2. In concurrent testing, singleton mode is not conducive to code debugging.
  3. The function code of singleton mode is usually written in a class. If the function design is unreasonable, it is easy to violate the principle of single responsibility.

4. Application scenario

  1. For some classes that need to be created frequently, using singleton can reduce the memory pressure of the system and reduce GC.
  2. A class only requires the generation of an object, such as the ID number of each person.
  3. Some classes consume more resources when creating instances, or the instantiation takes a long time and is often used.
  4. When a class needs frequent instantiation and the created objects are frequently destroyed, such as multithreaded thread pool, network connection pool, etc.
    5. When the object needs to be shared.

Implementation mode

1. Lazy mode (thread unsafe)

/**
 * Lazy mode (thread unsafe)
 * @author winter
 */
public class Singleton_01 {
    private static Singleton_01 instance;
    private Singleton_01() {
    }
    public static Singleton_01 getInstance(){
        if (null != instance) {
            return instance;
        }
        return new Singleton_01();
    }
}

Features: it can no longer be created externally, that is, new Singleton_01().
Problem: thread is unsafe. Multiple visitors get object instances at the same time, which will cause multiple identical instances to coexist.

2. Lazy mode (thread safety)

/**
 * Lazy mode (thread safe)
 * @author winter
 */
public class Singleton_02 {

    private static Singleton_02 instance;

    private Singleton_02() {
    }

    public static synchronized Singleton_02 getInstance() {
        if (null != instance) {
            return instance;
        }
        return new Singleton_02();
    }

}

Thread safety: directly add the lock to the method, and all accesses will grab the lock, resulting in waste of resources and low efficiency. It is not recommended.

3. Hungry man mode (thread safety)

/**
 * Hungry man mode (thread safe)
 * @author winter
 */
public class Singleton_03 {

    private static Singleton_03 instance = new Singleton_03();

    private Singleton_03() {
    }

    public static Singleton_03 getInstance() {
        return instance;
    }

}

Run the load directly at startup and obtain it directly when external needs to be used later, which will cause some memory waste problems.

4. Use the inner class of the class (thread safety)

/**
 * Use the inner class of the class (thread safe)
 * @author winter
 */
public class Singleton_04 {

    private static class SingletonHolder {
        private static Singleton_04 instance = new Singleton_04();
    }

    private Singleton_04() {
    }

    public static Singleton_04 getInstance() {
        return SingletonHolder.instance;
    }

}

It not only ensures thread safety, but also ensures lazy mode, and will not reduce performance due to locking. A more recommended singleton mode.

5. Double lock verification (thread safety)

/**
 * Double lock check (thread safe)
 * @author winter
 */
public class Singleton_05 {

    private static Singleton_05 instance;

    private Singleton_05() {
    }

    public static Singleton_05 getInstance(){
       if(null != instance) return instance;
       synchronized (Singleton_05.class){
           if (null == instance){
               instance = new Singleton_05();
           }
       }
       return instance;
    }

}

It realizes the optimization of method level lock, reduces the time-consuming of obtaining instances, and meets the lazy mode.

6.CAS (thread safety)

/**
 * CAS (Thread safe)
 * @author winter
 */
public class Singleton_06 {

    private static final AtomicReference<Singleton_06> INSTANCE = new AtomicReference<Singleton_06>();

    private static Singleton_06 instance;

    private Singleton_06() {
    }

    public static final Singleton_06 getInstance() {
        for (; ; ) {
            Singleton_06 instance = INSTANCE.get();
            if (null != instance) return instance;
            INSTANCE.compareAndSet(null, new Singleton_06());
            return INSTANCE.get();
        }
    }
    
}

When the thread competition is not fierce, compared with the implementation of other locks, there is no thread switching and blocking, no additional overhead, and can support large concurrency. But when the thread competition is fierce, CAS will always spin.

7. Enumerating singletons (thread safety)

/**
 * Enumerating singletons (thread safe)
 * @author winter
 */
public enum Singleton_07 {
    INSTANCE;
    public void doSomething() {
        System.out.println("doSomething");
    }
    //Call mode
    public static void main(String[] args) {
        Singleton_07.INSTANCE.doSomething();
    }
}

This method solves the problems of thread safety, free traversal and single instance, and is very concise. It is Joshua J. The singleton mode recommended by Bloch.

summary

Single example is the simplest design pattern, but it needs to use the basic skills of java in various implementations. It is also a design pattern frequently asked in interviews, such as 1 Please write an efficient and safe singleton mode? 2. Is lazy mode thread safe? Why?

Refer to redesigning java patterns

Keywords: Java Design Pattern Interview

Added by PurpleMonkey on Wed, 09 Feb 2022 16:11:36 +0200