This is the 6th day of my participation in the August More Text Challenge

Let’s start today with Java’s singleton pattern, which is being updated.

Let’s learn about design patterns, say they are fundamental and fundamental, say they are not, and they are not. It’s here and there. Learn it well is also to let oneself further bar. Like a sentence: “eight hours for life, eight hours for development”.

'

Cover location: 😂 I have no idea

Author: L

Design Mode series:

  • Java Design pattern – singleton pattern
  • Java Design Pattern – Factory Pattern (1) Simple Factory pattern
  • Java Design Pattern – Factory Pattern (2) Factory method pattern
  • Java Design Pattern – Factory Pattern (3) Abstract Factory pattern
  • Java Design pattern – Builder pattern
  • Java Design pattern – Proxy pattern
  • Java Design pattern – Adapter pattern
  • Java Design pattern – Decorator pattern
  • Java Design pattern – Bridge pattern
  • Java Design pattern – Appearance pattern
  • Java Design pattern – Composite pattern
  • Java Design pattern – Share meta pattern
  • Java Design Pattern – Template method pattern
  • Java Design pattern – Policy pattern
  • Java Design pattern – Chain of Responsibility pattern
  • Java Design Pattern – The Mediator pattern
  • Java Design Pattern – Observer Pattern (publish/subscribe pattern)
  • Continuously updated…

One, foreword

Concept:

The singleton pattern is a common software design pattern belonging to the creation type. Classes created by singleton mode have only one instance in the current process (depending on the need, it may also be a singleton in a thread, such as: only use the same instance in thread context)

Application:

The singleton pattern allows us to create only one object, avoiding the memory consumption and garbage collection associated with frequent object creation.

The singleton pattern allows only one object to be created, thus saving memory and speeding up object access. Therefore, objects need to be suitable for use in common situations, such as multiple modules using the same data source to connect objects, and so on. 1. Objects that need to be frequently instantiated and then destroyed. 2. Frequently used objects that consume too much time or resources when creating objects. 3. Stateful tool objects. 4. Objects that frequently access databases or files.

Specific application in the project:

  1. Encapsulate some common tool classes to ensure common application data consistency
  2. Store some shared data in memory that other classes can read at any time.

Principles and procedures for implementing the singleton pattern:

1. Singleton mode: Ensure that a class has only one instance, instantiate it and provide instance 2 to the system. Classification of singletons: hungry singletons (instantiating an object as a reference to itself while loading a class), lazy singletons (instantiating an object when calling a method such as getInstance) 3. Singleton elements: a. Private constructor b. private static reference to own instance C. A public static method that returns its own instance

Method:

There are eight ways to use the singleton pattern:

  1. Hungry (static constant)
  2. Hungry (static code block)
  3. Lazy (thread-unsafe)
  4. Lazy (thread-safe, synchronous approach)
  5. Lazy (thread unsafe, synchronized code blocks)
  6. Slob (double check)
  7. Lazy (static inner class)
  8. Enumeration implementation

Second, singleton pattern code implementation and analysis

2.1 hungry (static constant)

Code implementation:

/** * singleton mode *@Author: crush
 * @Date: 2021-08-06 9:14
 * version 1.0
 */
public class SingletonTest1 {
    public static void main(String[] args) {
        // The object is a singleton
        Singleton singleton = Singleton.getInstance();
        Singleton singleton1 = Singleton.getInstance();

        System.out.println(singleton == singleton1);

        System.out.println("singleton hashcode:"+singleton.hashCode());
        System.out.println("singleton1 hashcode:"+singleton1.hashCode());
        Singleton hashCode :24324022 singleton1 hashCode :24324022 */}}/** ** ** ** ** ** ** ** ** ** ** **
class Singleton{
    /*** privatize the constructor */
    private Singleton(a){};
    
    /** * There is no thread-safety problem with creating an object instance inside a class that is loaded with the current class load. * /
    private final static Singleton INSTANCE=new Singleton();
    
    /*** provides a public method to return the static constant */
    public static Singleton getInstance(a){
        returnINSTANCE; }}Copy the code

Conclusions and Advantages:

  1. Advantages: Hanky-hank (static constant mode) it does not have to worry about thread safety, it is instantiated at class load time.

  2. Disadvantages: The disadvantage is that once the class is loaded, it will be instantiated directly, not lazily loaded. If you never use the class, you will waste memory.

    Note: You may be thinking that the classes are already loaded, so why shouldn’t I be there?

    GetInstance is a static method that lets the class load. Similarly, if there are other static methods in the class, when you call it, it will load the class.

  3. Summary: This singleton approach can be used, at least without worrying about thread synchronization. Classes that are used very frequently can use this approach without any problems other than memory waste.

2.2 hungry (Static code block)

/** * singleton mode 2 **@Author: crush
 * @Date: 2021-08-06 9:14
 * version 1.0
 */
public class SingletonTest1 {
    public static void main(String[] args) {
        // The object is a singleton
        Singleton singleton = Singleton.getInstance();
        Singleton singleton1 = Singleton.getInstance();

        System.out.println(singleton == singleton1);

        System.out.println("singleton hashcode:" + singleton.hashCode());
        System.out.println("singleton1 hashcode:" + singleton1.hashCode());
        Singleton hashCode :24324022 singleton1 hashCode :24324022 */}}/** ** ** ** ** ** ** ** ** ** ** ** ** ** **
class Singleton {

    /** * privatize the constructor */
    private Singleton(a) {}/** * There is no thread-safety problem with creating an object instance inside a class that is loaded with the current class load. * /
    private static Singleton singleton;

    static {
        // Create a singleton in a static code block instead
        singleton = new Singleton();
    }

    /** * provides a public method to return the static constant */
    public static Singleton getInstance(a) {
        returnsingleton; }}Copy the code

Conclusion: This approach is very similar to the first, except that the instantiation of the class is placed in a static code block. Advantages and disadvantages of the same hungry han type (static constant).

2.3, lazy (thread unsafe)

/** * singleton mode **@Author: crush
 * @Date: 2021-08-06 9:14
 * version 1.0
 */
public class SingletonTest3 {
    public static void main(String[] args) {

        // Lazy thread is an unsafe way to use a single thread
        //=========== is safe under single thread, the test code is the same as the first ===========
        // ========= simulate multi-threading under =============
        Runnable runnable = new Runnable(){
            @Override
            public void run(a) { Singleton instance = Singleton.getInstance(); System.out.println(instance.hashCode()); }}; Runnable runnable2 =new Runnable(){
            @Override
            public void run(a) { Singleton instance1 = Singleton.getInstance(); System.out.println(instance1.hashCode()); }}; Thread thread1 =new Thread(runnable);
        Thread thread2 = new Thread(runnable2);
        thread1.start();
        thread2.start();
        /** * the result is not unique, * may be the same, may be different, several times, you can find that the thread is not safe. * 94433 * 21648409 */}}/** * Lazy threads are not safe */
class Singleton {

    /*** privatize the constructor */
    private Singleton(a) {}
    
    /*** There is no thread-safety problem with creating an object instance inside a class that is loaded with the current class load. * /
    private static Singleton singleton;

    /** * provide a public method * when this method is used, create the singleton */
    public static Singleton getInstance(a) {
        if(singleton==null) {// Simulate multithreading by blocking here
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            singleton= new Singleton();
        }
        returnsingleton; }}Copy the code

Conclusions and Advantages:

  1. Advantages: play a lazy loading effect
  2. Disadvantages: Thread is not safe, if in multithreading, the first thread entersif(singleton==null)But before the next thread is executed, a second thread follows and entersif(singleton==null), multiple instances will be created. It’s not a singleton pattern.
  3. Suggestion: do not use this method for development. The thread safety problem cannot be solved, namely đŸ˜±.

2.4 lazy (thread-safe, synchronous method)

/** * singleton mode **@Author: crush
 * @Date: 2021-08-06 9:14
 * version 1.0
 */
public class SingletonTest4 {
    public static void main(String[] args) {

        // Lazy thread is an unsafe way to use a single thread
        //=========== single thread is safe ===========
        // ========= simulate multi-threading under =============
        Runnable runnable = new Runnable(){
            @Override
            public void run(a) { Singleton instance = Singleton.getInstance(); System.out.println(instance.hashCode()); }}; Runnable runnable2 =new Runnable(){
            @Override
            public void run(a) { Singleton instance1 = Singleton.getInstance(); System.out.println(instance1.hashCode()); }}; Thread thread1 =new Thread(runnable);
        Thread thread2 = new Thread(runnable2);
        thread1.start();
        thread2.start();
        / * * 6902734 6902734 * /}}/** ** ** /
class Singleton {

    /*** privatize the constructor */
    private Singleton(a) {}
    
    /*** There is no thread-safety problem with creating an object instance inside a class that is loaded with the current class load. * /
    private static Singleton singleton;


    /** * provide a public method * when used, create singleton * add the synchronized keyword to address thread-safety issues */
    public static synchronized Singleton getInstance(a) {
        if(singleton==null) {// Simulate multithreading by blocking here
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            singleton= new Singleton();
        }
        returnsingleton; }}Copy the code

Conclusions and Advantages:

  • In fact, code and lazy threads are not safe implementation, is inSingleton getInstance() That’s one too manysynchronizedChange this method into a synchronous method, which solves the thread synchronization problem.
  • Disadvantages: but because of the method addedsynchronizedKeyword, which reduces the execution efficiency. And every time you fetch it after that, you have to synchronize it, but essentially this code executes once, and then retrun is optimal, and the method synchronization is a huge drag.
  • This method is not recommended. Although thread synchronization is achieved, it is inefficient and affects the usage.

2.5. Lazy (thread-unsafe synchronized code blocks)

package com.crush.singleton05;

/** * singleton mode **@Author: crush
 * @Date: 2021-08-06 9:14
 * version 1.0
 */
public class SingletonTest5 {
    public static void main(String[] args) {

        // Lazy thread is an unsafe way to use a single thread
        //=========== is safe under single thread, code as above ===========
        // ========= simulate multi-threading under =============
        Runnable runnable = new Runnable() {
            @Override
            public void run(a) { Singleton instance = Singleton.getInstance(); System.out.println(instance.hashCode()); }}; Runnable runnable2 =new Runnable() {
            @Override
            public void run(a) { Singleton instance1 = Singleton.getInstance(); System.out.println(instance1.hashCode()); }}; Thread thread1 =new Thread(runnable);
        Thread thread2 = new Thread(runnable2);
        thread1.start();
        thread2.start();
        /** * If so, multithreading is not safe. 20775718 5987586 * /}}/** * this is a thread safety issue
class Singleton {

    /** * privatize the constructor */
    private Singleton(a) {}/*** There is no thread-safety problem with creating an object instance inside a class that is loaded with the current class load. * /
    private static Singleton singleton;

    /** * provide a public method * When used, create singleton * add synchronized */ to the synchronized code block
    public static Singleton getInstance(a) {
        if (singleton == null) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (Singleton.class) {
                singleton = newSingleton(); }}returnsingleton; }}Copy the code

Conclusions and Advantages:

1) In fact, the original intention is to make an optimization of the previous way, in order to improve the synchronization efficiency, to this way of synchronizing code blocks

2) But in practice, this does not work as thread synchronization, and the problem is the same as the previous approach.

3) It is also not recommended to implement the singleton pattern in this way.

2.6 slob style (double check)

/** * singleton mode **@Author: crush
 * @Date: 2021-08-06 9:14
 * version 1.0
 */
public class SingletonTest6 {
    public static void main(String[] args) {

        // Slacker thread-safe mode, suitable for single, multi-threaded use
        //=========== is safe under single thread, code as above ===========
        // ========= simulate multi-threading under =============
        Runnable runnable = new Runnable() {
            @Override
            public void run(a) { Singleton instance = Singleton.getInstance(); System.out.println(instance.hashCode()); }}; Runnable runnable2 =new Runnable() {
            @Override
            public void run(a) { Singleton instance1 = Singleton.getInstance(); System.out.println(instance1.hashCode()); }}; Thread thread1 =new Thread(runnable);
        Thread thread2 = new Thread(runnable2);
        thread1.start();
        thread2.start();
        /** * Thread safety * 7739563 * 7739563 */}}/** ** */
class Singleton {

    /*** privatize the constructor */
    private Singleton(a) {}/*** There is no thread-safety problem with creating an object instance inside a class that is loaded with the current class load. * /
    private static Singleton singleton;


    /** * provide a public method * when used, create singleton * add synchronized * double-check */ at synchronized code blocks
    public static Singleton getInstance(a) {
        if (singleton == null) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (Singleton.class) {
                if(singleton==null){
                    singleton = newSingleton(); }}}returnsingleton; }}Copy the code

Conclusions and Advantages:

1) We performed two if (singleton == NULL) operations in the code, one outside the synchronized code block, one inside the synchronized code block, and two checks to ensure thread safety.

2) In this case, the synchronized code only needs to be executed once, and the Singleton only needs to be instantiated once, which not only achieves lazy loading, but also ensures thread safety and improves execution efficiency.

3) Conclusion: Lazy loading, thread-safe, efficient, of course.

2.7 lazy (Static inner Class)

/** * singleton mode **@Author: crush
 * @Date: 2021-08-06 9:14
 * version 1.0
 */
public class SingletonTest7 {
    public static void main(String[] args) {

        // Slacker thread-safe mode, suitable for single, multi-threaded use
        //=========== is safe under single thread as above ===========
        // ========= simulate multi-threading under =============
        Runnable runnable = new Runnable() {
            @Override
            public void run(a) { Singleton instance = Singleton.getInstance(); System.out.println(instance.hashCode()); }}; Runnable runnable2 =new Runnable() {
            @Override
            public void run(a) { Singleton instance1 = Singleton.getInstance(); System.out.println(instance1.hashCode()); }}; Thread thread1 =new Thread(runnable);
        Thread thread2 = new Thread(runnable2);
        thread1.start();
        thread2.start();
        /** * Thread safety * 7739563 * 7739563 */}}/** ** */
class Singleton {

    /*** privatize the constructor */
    private Singleton(a) {}/** * write a static inner class and then write a static constant Singleton */ inside the class
    private static class SingletonInstance {
        private final static Singleton SINGLETON=new Singleton();
    }


    /** * Provide a public method * when this method is used, load SingletonInstance to get Singleton instance */
    public static Singleton getInstance(a) {
        returnSingletonInstance.SINGLETON; }}Copy the code

Conclusions and Advantages:

1) This approach also does not cause thread synchronization problems and also borrows the JVM’s classloading mechanism to ensure that only one thread is instantiated.

2) The static internal SingletonInstance class will not be instantiated immediately when the Singleton is loaded. Instead, the SingletonInstance class will be loaded only when the getInstance method is called.

3) The static properties of a class are initialized only when the class is loaded for the first time, whereas in this case the JVM’s classloading mechanism helps ensure thread-safety.

4) Summary: Avoid thread safety issues, use static internal class lazy loading (do lazy loading), high efficiency, isn’t it more fun, use it.

2.8, enumeration class implementation

/** * singleton mode **@Author: crush
 * @Date: 2021-08-06 9:14
 * version 1.0
 */
public class SingletonTest8 {
    public static void main(String[] args) { Singleton singleton1 = Singleton.SINGLETON; Singleton singleton2 = Singleton.SINGLETON; System.out.println(singleton1 == singleton2); System.out.println(singleton1.hashCode()); System.out.println(singleton2.hashCode()); }}/** * 2
enum Singleton {
    SINGLETON;
}
Copy the code

Conclusions and Advantages:

  • No multithreading problems, high efficiency, can prevent deserialization to recreate the object, is also recommended.

Note: In general, the hanhanian form is used, and surprisingly convenient, if you care about resources, usually use static inner class. But all the use, are specific problems specific analysis, there is no best, only the most suitable.

The use of singletons in some source code

3.1 and JDK

For example, the Runtime in the JDK is implemented in a hanhan-style singleton

3.2, Mybatis

The MybatisErrorContextforThreadLocalThread-unique

Spring also has a lot of doha, I didn’t go to find one. 👹 đŸŠČ

4. Talk to yourself

You roll me roll, everyone roll, when this road is the end ah.

Sometimes I want to stop and have a rest. It’s hard to stick to one thing all the time. đŸ‘© đŸ’»

Hi, if you happen to read this article and think it’s good for you, give it a thumbs up and let me feel the joy of sharing, Crab.

If there is something wrong, please don’t add!!

Similarly, if there is any doubt, please leave a message or private message, we will reply to you in the first a time.

Ongoing update