Notes on JAVA design patterns

  1. Singleton mode

         one point one   brief introduction

         The so-called class singleton design pattern is to take certain methods to ensure that there can only be one object instance for a class in the whole software system, and the class only provides a method to obtain its object instance (static method).         

        one point two   Eight ways to create proxy patterns

         Method 1: evil Chinese formula 1-static variable (No Lazy)

public class Singleton1 {
    //1. Privatization of constructor
    private Singleton1() {}

    //2. Create a static object instance
    private static final Singleton1 INSTANCE = new Singleton1();

    //3. Object instances returned by public methods
    public static Singleton1 getInstance() {
        return INSTANCE;
    }

}

Excellent: complete instantiation when loading classes to avoid thread safety problems

Missing: non lazy loading will cause a waste of memory

Conclusion: it is available, but it will cause a waste of memory

        Method 2: evil Chinese 2-static code block (No Lazy)

public class Singleton2 {
    //1. Privatization of constructor
    private Singleton2() {}

    //2. Create static variables
    private static Singleton2 INSTANCE;

    //3. Create an instance using static code blocks
    static {
        INSTANCE = new Singleton2();
    }

    //4. Object instances returned by public methods
    public static Singleton2 getInstance() {
        return INSTANCE;
    }
}

The advantages and disadvantages are similar to those above

        Method 3: lazy 1- static method (thread unsafe)

public class Singleton3 {
    //1. Privatization of constructor
    private Singleton3() {}

    //2. Create static variables
    private static Singleton3 singleton3;

    //4. Object instances returned by public methods
    public static Singleton3 getInstance() {
        if (singleton3 == null) {
            singleton3 = new Singleton3();
        }
        return singleton3;
    }
}

Excellent: lazy loading

Missing: thread unsafe

Summary: do not use

         Method 4: lazy 2- synchronization method (thread safety)

public class Singleton4 {
    //1. Privatization of constructor
    private Singleton4() {}

    //2. Create static variables
    private static Singleton4 singleton4;

    //3. Object instances returned by public methods
    public static synchronized Singleton4 getInstance() {
        if (singleton4 == null) {
            singleton4 = new Singleton4();
        }
        return singleton4;
    }
}

Excellent: thread safety

Lack of: low efficiency,   When each thread wants to obtain an instance of a class, it must synchronize the getInstance() method.  

         Method 5: lazy 3-synchronous code block (non realizable singleton)

public class Singleton5 {
    //1. Privatization of constructor
    private Singleton5() {}

    //2. Create static variables
    private static Singleton5 singleton5;

    //3. Object instances returned by public methods
    public static  Singleton5 getInstance() {
        if (singleton5 == null) {
            synchronized (Singleton5.class) {
                singleton5 = new Singleton5();
            }
        }
        return singleton5;
    }
}

The original intention is to improve method 4, but there is a thread safety problem, which can not be used

        Method 6: double check - synchronous code block

public class Singleton6 {
    //1. Privatization of constructor
    private Singleton6() {}

    //2. Create static variables
    //volatile keyword is used to ensure the visibility of shared variables between different threads,
    // That is, when one thread modifies the variable modified by volatile, another thread will immediately see the latest value, which is more conducive to thread safety
    private static volatile Singleton6 singleton6;

    //3. Object instances returned by public methods
    public static Singleton6 getInstance() {
        if (singleton6 == null) {
            synchronized (Singleton6.class) {
                if (singleton6 == null) {
                    singleton6 = new Singleton6();
                }
            }
        }
        return singleton6;
    }
}

Double check: only the threads that enter the outer if statement at the beginning need to wait synchronously. Subsequent threads will not enter the outer if statement and return directly

         Method 7: static inner class

public class Singleton7 {
    //1. Privatization of constructor
    private Singleton7() {}

    //2. Create static inner class
    private static class SingletonInstance {
        private static final Singleton7 INSTANCE = new Singleton7();
    }

    //3. Object instances returned by public methods
    public static Singleton7 getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

The class loading mechanism is used to ensure that there is only one object during instantiation. The SingletonInstance class will be loaded only when the getInstance() method is called, so as to realize lazy loading. Because the static INSTANCE attribute of the internal class will only be loaded once by the, thread insecurity is avoided (similar to method 1, but the loading of static variables is delayed)

        Method 8: enumeration class

public enum Singleton8 {

    INSTANCE;

    public void method() {
        // to do...
    }
}

Super simple, not easy to make mistakes

Moreover, the enumeration class implements a serializable interface, which can also prevent deserialization from creating new objects

The enumerated attribute has its own public static final modifier, which is a static attribute

        one point three   summary

Singleton mode lazy load thread safe deserialization   Recommended use   

Comparison of eight singleton modes (in order)
Singleton modeLazy loadingThread safetyDeserializationRecommended use (grade)
Hungry Han style 1
Hungry Han style 2
Lazy 1
Lazy 2
Lazy 3
duplication check✅✅
Static inner class

✅✅

Enumeration class✅✅✅

Keywords: Java Design Pattern

Added by csteff24 on Tue, 05 Oct 2021 23:29:38 +0300