Understand the term

Singleton Design Pattern is a creative Design Pattern.

Singleton: a class that allows only one object (or instance) to be created is a singleton;

role

  1. From the business concept, some data should only be kept in one copy of the system, which is better designed as a singleton class. For example, the system configuration information class.
  2. Use singletons to resolve resource access conflicts

Key implementation steps

  • The hungry type
  1. Private construction method
  2. A static instance of instance is defined and initialized during class loading
  3. Define the static method getInstance

Hungry type is implemented in class loading period, has been the instance static instance initialization is good, so, the instance instance creation is thread-safe. However, this implementation does not support lazy loading instances.

  • Double check slob
  1. Private construction method
  2. Define a volatile static instance variable
  3. Define static method getInstance, first check whether instance is null, if it is synchronized lock singleton class, then check whether instance is null, if it is initialized.

The dual detection implementation supports both lazy loading and high concurrency singleton implementation. Once instance is created, calling getInstance() does not enter the locking logic. So, this implementation solves the problem of lazy concurrency.

  • Static inner class
  1. Private construction method
  2. Define an internal static private class SingletonHolder, and inside the SingletonHolder define an external class variable of private static final type instance, and initialize it
  3. The external class defines a static method getInstance that returns SingletonHolder.instance

Use Java’s static inner classes to implement singletons. This implementation, which supports both lazy loading and high concurrency, is also simpler to implement than dual detection.

  • The enumeration
  1. Define an enumeration class
  2. Define an enumeration called INSTANCE
  3. Define the remaining variables and methods
  4. Call the instance. XXX method directly when used

The simplest implementation is a singleton implementation based on enumerated types. This implementation ensures thread-safe and unique instance creation through the nature of Java enumerated types.

Code sample

The hungry type


public class IdGenerator { 
  private AtomicLong id = new AtomicLong(0);
  private static final IdGenerator instance = new IdGenerator();
  private IdGenerator(a) {}
  public static IdGenerator getInstance(a) {
    return instance;
  }
  public long getId(a) { 
    returnid.incrementAndGet(); }}Copy the code

Double check slob


public class IdGenerator { 
  private AtomicLong id = new AtomicLong(0);
  private static IdGenerator instance;
  private IdGenerator(a) {}
  public static IdGenerator getInstance(a) {
    if (instance == null) {
      synchronized(IdGenerator.class) { // This is a class level lock
        if (instance == null) {
          instance = newIdGenerator(); }}}return instance;
  }
  public long getId(a) { 
    returnid.incrementAndGet(); }}Copy the code

Static inner class


public class IdGenerator { 
  private AtomicLong id = new AtomicLong(0);
  private IdGenerator(a) {}

  private static class SingletonHolder{
    private static final IdGenerator instance = new IdGenerator();
  }
  
  public static IdGenerator getInstance(a) {
    return SingletonHolder.instance;
  }
 
  public long getId(a) { 
    returnid.incrementAndGet(); }}Copy the code

The enumeration

public enum IdGenerator {
  INSTANCE;
  private AtomicLong id = new AtomicLong(0);
 
  public long getId(a) { 
    returnid.incrementAndGet(); }}Copy the code

Classic application

  • Spring Bean management