There are three main types of design patterns that are treated differently in design patterns: creation patterns, structural patterns, and behavior patterns.

Abstract Factory Pattern Builder Pattern Prototype Pattern Singleton Pattern

define

It is defined to ensure that there is only one instance of a class and to provide a global access point. Singleton pattern is one of the most simple mode of the whole design, because in the programming development often encounter such a scenario, it is need to make sure that even if a class has only one instance multithreaded access at the same time, in conclusion, and common development, we can summarize the experience, the singleton pattern is mainly to solve is that a global use of such frequent creation and consumption, thereby Improve overall code performance.

Seven implementations of the singleton pattern

1. Slacker mode (thread unsafe)

/** * Lazy * it is not safe to create threads when needed */
private static Singleton singleton;

public static Singleton getInstance(a) {
    if (singleton == null) {
        singleton = new Singleton();
    }
    return singleton;
}
Copy the code

advantages

Lazy loading does not waste resources.

disadvantages

In a concurrent environment. It is possible to produce multiple singletons. Thread unsafe

2. Lazy synchronous lock (thread safe)


/** * Lazy locking with synchronization * Thread safe, not wasteful, inefficient * Description: This method has good lazy loading and works well in multiple threads * However, it is inefficient and does not require synchronization in most cases. * Advantages: initializes on the first call, avoiding memory waste. * Cons: Synchronized is required to ensure singletons, but it is inefficient. * The performance of getInstance() is not critical to the application (this method is not used very often). * /
private static Singleton singleton2;

public static synchronized Singleton getInstance2(a) {
    if (singleton2 == null) {
        singleton2 = new Singleton();
    }
    return singleton2;
}
Copy the code

advantages

  • Thread safety
  • Lazy loading does not waste resources.

disadvantages

Efficiency is low. Synchronization locks are not required in most cases.

3. Hungry (thread safe)

/** * Thread-safe waste of resources * Description: This method is common, but easy to generate garbage objects. * Advantages: No lock, better execution. * Cons: Class is initialized when it is loaded, wasting memory. * It uses the ClassLoader mechanism to avoid multi-threaded synchronization problems, however, instance is instantiated when the class loads. * Although there are many reasons for class loading, most singletons call the getInstance method. However, it is not clear that there is any other way (or any other static method) to cause class loading, * initializing instance in this case is not lazy loading. * /
private static Singleton singleton3 = new Singleton();

public static Singleton getInstance3(a) {
    return singleton3;
}
Copy the code

advantages

Thread-safe, class-based singletons are created when the object is loaded. Only one object exists in the entire JVM environment

disadvantages

Easy to generate garbage objects

4. Double Check (thread safe)

/** * Double locking * double check-locking * JDK version: JDK1.5 * Lazy initialization: yes * Multithreaded security: Yes * Implementation difficult: more complex ** Description: This method adopts double locking mechanism, which is safe and can maintain high performance in multithreaded situations. * The performance of getInstance() is critical to the application. * /
private static Singleton singleton4;
public static Singleton getInstance4(a) {
    if (singleton4 == null) {
        synchronized (Singleton.class) {
            if (singleton4 == null) {
                singleton4 = newSingleton(); }}}return singleton4;
}
Copy the code

advantages

  • Lazy loading
  • Thread safety

disadvantages

Efficiency is low. It is inefficient because of the synchronous locking mode.

5. Static inner classes (thread-safe)

/** * Registered/static inner class * whether Lazy initialization: yes * Whether multi-threaded security: yes * Implementation difficulty: general * Description: This method can achieve the same effect as double lock mode, but the implementation is simpler. Use delayed initialization for static fields, which should be used instead of double-locking. This mode is only suitable for static domains. The double-check mode can be used when the instance domain requires delayed initialization. * This method also uses the ClassLoader mechanism to ensure that the instance is initialized with only one thread. This method is different from the third method: If the Singleton class is loaded, the instance will be instantiated. If the Singleton class is loaded, the instance will not be initialized. Because the SingletonHolder class is not actively used, the SingletonHolder class will be explicitly loaded and instantiated only by explicitly calling the getInstance method. Imagine if instantiating instance is resource-intensive, so you want it to be loaded lazily, but on the other hand, you don't want to instantiate it when the Singleton class is loaded, because there's no guarantee that the Singleton class might be actively used elsewhere to be loaded, It is not appropriate to instantiate instance at this time. At this point, this approach makes more sense than the third approach. * * /
private static class SingletonHolder{
    private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance5(a){
    return SingletonHolder.INSTANCE;
}
Copy the code

advantages

  • Classloader loads static inner classes to ensure that singleton classes are not loaded until they are called. There is no waste of resources
  • Thread safety

disadvantages

  • There are no obvious drawbacks. If anything, it makes the structure a little more complicated. But this pattern fits all perfectly. But to be practical. The most common way to create singletons is to use static classes.

6. Static classes (thread-safe)

public static Singleton singleton6 = new Singleton();
Copy the code

advantages

Simple and convenient. Ideal for use during development

disadvantages

Not lazy loading.

7. Enumeration (thread-safe)

public enum Singletons{
    INSTANCE;
    Singletons() {
    }
}
public static Singletons getInstance7(a){
    return Singletons.INSTANCE;
}
Copy the code

Enumeration Singletons recommended by Effective Java authors (Thread-safe)

  • The Effective Java authors recommend using enumerations to solve the singleton pattern, which is probably the least commonly used approach.
  • This approach solves the main problem; Thread safe, free serialization, single instance.