"Head First Design Patterns" study notes - Singleton

Today term singleton pattern is relatively simple class structure a design pattern, in fact, he had only one class. Ha ha ha, that we are going to see it.

public class Singleton {
    private static Singleton uniqueInstance;
    
    private Singleton() {}

    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

First there is defined a property of this class privatization, followed by a constructor privatization, only call the constructor in this class, the following is focused, through getInstance () method can be obtained such that the outside of this class object class, the first is a judgment, if this class attribute uniqueInstance is empty, the instance of a property, or direct return this property to ensure that we have only one object.

Singleton ensure that only one instance of a class, and provide a global access point.

When the getInstance () method we can delay the instantiation of this class, this uniqueInstance class property is the only instance of this class of objects, only the first time to use this object, which is the first call getInstance () method uniqueInstance be instantiated, then later when the class, the property returns directly.

But this code is not impeccable, the case of multi-threaded and uses this code is simply a disaster, and now we look at how to solve:

public class SingletonThread {
    private static SingletonThread uniqueInstance;
    
    private SingletonThread() {}
    
    public static synchronized SingletonThread getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new SingletonThread();
        }
        return uniqueInstance;
    }
}

That is, by increasing the synchronized keyword to the getInstance () method, forcing each thread before entering into this method to wait until other threads out of the method. But this is still a problem, first of synchronization can degrade performance, and secondly, we have only the first instance of this attribute when you need to set the synchronization, once set up uniqueInstance do not need to sync, so every time synchronization is behind the excess A step of.

So we can load on the well when the class is instantiated work in JVM, look at the following code:

public class SingletonFirst {
    private static SingletonFirst uniqueInstance = new SingletonFirst();
    
    private SingletonFirst() {}
    
    public static SingletonFirst getInstance() {
        return uniqueInstance;
    }
}

When we loaded the class in JVM, you can create a unique singleton instance immediately. You will first create an instance of JVM guarantee before any thread to access the static variable.

Another method, using a "double checking locks", reducing the use of synchronization getInstance (), the code is as follows:

public class SingletonDouble {
    private volatile static SingletonDouble uniqueInstance;
    
    private SingletonDouble() {}
    
    public static SingletonDouble getInstance() {
        if (uniqueInstance == null) {
            synchronized (SingletonDouble.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new SingletonDouble();
                }
            }
        }
        return uniqueInstance;
    }
}

This way, we can significantly reduce the time consumption, first check the examples, if not, enter the synchronized block, once again check instance, if it does not create, attention, block synchronization code, we will only be executed once, only the first times before synchronization. Double-checked locking mechanism does not apply to versions 1.4 and earlier.

Well, all singleton pattern implementation would have finished, remember to take it.

Published 26 original articles · won praise 2 · Views 2328

Guess you like

Origin blog.csdn.net/qq_42909545/article/details/104895625