One, foreword

Singleton is a common design pattern. Its definition is that singleton object class allows only one instance to exist, and the core principle of implementation is the privatization of constructors. Using singletons saves memory overhead and is a mapping in real-world scenarios, such as a printer that can only run one print task at a time, a company that has only one CEO, and so on.

Two, implementation steps

2.1 Privatize constructors; 2.2 Provide a static method to get instances (multithreading issues need to be noted).

Third, writing

3.1 Hungry (Thread-safe)

public class Singleton {

    private static final Singleton instance = new Singleton();

    private Singleton() {
    }

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

Advantages: simple and crude, class loading is completed when the initialization, thread safety; Disadvantages: The class is initialized when it is loaded. If the object is used late or never used, it wastes unnecessary memory resources.

3.2 Lazy (Thread unsafe)

public class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

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

Advantages: Delayed initialization, avoiding unnecessary memory overhead; Disadvantages: Thread insecurity.

3.3 Lazy (thread-safe, synchronous method)

public class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

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

Advantages: Delayed initialization, avoiding unnecessary memory overhead, and thread safety; Disadvantages: Low efficiency, every time to acquire the instance of the synchronization lock, in fact, only need to synchronize the lock when the first new object, the subsequent acquisition of the instance can be directly returned.

3.4 Lazy (thread-safe, synchronized code blocks)

public class Singleton {

    private static volatile Singleton instance;

    private Singleton() {
    }

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

This is an improvement over 3.3, efficient and thread-safe, and is a common option. (Thanks to @monkeysayhi and @java bear, volatile is now added to avoid instruction reordering.)

3.5 Static Inner Classes (Thread-safe)

public class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        returnSingletonHolder.INSTANCE; } private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); }}Copy the code

This approach takes into account delayed initialization, thread safety, is a relatively recommended writing method.

3.6 Enumeration (Thread Safety)

public enum Singleton {

    INSTANCE;

}Copy the code

Enumeration is a new feature released in JDK1.5. It is recommended by Effective Java. It is simple, efficient, and thread-safe, but not very readable.

Four, applicable scenarios

4.1 Creating objects takes too much time or resources, but they are frequently used. 4.2 Objects that need to be frequently created and destroyed; 4.3 Tool Objects.Copy the code

Five, the summary

There are many ways to write singletons. The common ones listed above need to be written according to the actual needs of your application. I personally recommend 3.4 lazy (thread-safe, synchronized code blocks) and 3.5 static inner classes (thread-safe).