define

The Singleton Pattern is one of the simplest design patterns in Java. This type of design pattern is the creation pattern, which provides the best way to create objects.

This pattern involves a single class that is responsible for creating its own objects while ensuring that only a single object is created. This class provides a way to access its unique objects directly, without instantiating the objects of the class.

The third hangry method is recommended. Static inner classes are used only when the lazy loading effect is explicitly implemented. If it comes to deserializing objects, try using enumerations. If you have other special requirements, you can consider using a double check mode

1. The hungry

It doesn’t work so let me create it first. It’s thread safe but it takes up memory

public class SingleTest {
    private static SingleTest singleTest=new SingleTest();
    private SingleTest(a){};
    public static SingleTest getInstance(a){
        
        returnsingleTest; }}Copy the code

2. LanHanShi

Reload as needed, but not thread safe.

public class SingleTest {
    private static SingleTest singleTest;
    private SingleTest(a){};
    public static SingleTest getInstance(a){
        if (singleTest==null)
            singleTest=new SingleTest();
        returnsingleTest; }}Copy the code

3. Lazy, thread-safe

Double check and lock

public class SingleTest {
    private static  volatile SingleTest singleTest;
    private SingleTest(a){};
    public static SingleTest getInstance(a){
        Thread A and thread B check whether they exist
        if (singleTest==null) {Thread A gets the lock first, thread B blocks
            synchronized (SingleTest.class){
                 // Thread A creates the object, assigns the value, returns the lock, thread B enters the judgment is not null end.
                if (singleTest==null)
                Since new is not an atomic operation and can cause problems with instruction reordering, we add volatile to this property
                // The creation of an object involves allocating space - initializing the object - pointing to space
                // Problem: thread A creates the object, performs the allocation of space, the object points to space
                // Thread B goes in and gets the object, returns a reference, and the object is not actually initialized
                singleTest=newSingleTest(); }}returnsingleTest; }}Copy the code

4. Static inner class implementation

The SingleTest class is loaded and SingleTest may not be initialized. Because the SingleHolder class is not actively used, singleTest is instantiated by explicitly loading the SingletHolder class only when the getInstance method is explicitly called. Thread safety.

public class SingleTest {
    private SingleTest(a){};
    public static SingleTest getInstance(a){
        return SingleHolder.singleTest;
    }
    public static final class SingleHolder{
        private static final SingleTest singleTest=newSingleTest(); }}Copy the code

5. Enumeration implementation – The best way to implement the singleton pattern

The previous modes can all be broken by reflection, and Enum guarantees this

public enum  EnumTest {
    Instance;
    public EnumTest getInstance(a){
        returnEnumTest.Instance; }}Copy the code