Design pattern --- singleton pattern

☺ For the singleton mode, personal learning needs to master

  • Note that the key points of the answers are blackened. For the singleton mode, master, the following points are great.

  • Friends who are interested in knowing the content and more related learning materials, please like and collect + comment and forward + follow me, there will be a lot of dry goods later. I have some interview questions, architecture, and design materials that can be said to be necessary for programmer interviews!
    All the materials are organized into the network disk, welcome to download if necessary! Private message me to reply [111] to get it for free

1. Know what a singleton is:

Answer: A class has one and only one instance , [ 单例]. The singleton mode ensures that there is only one object of this class in the system memory, saving system resources . For some objects that need to be created and destroyed frequently, using the singleton mode can improve the system performance. When instantiating an object , it is through the corresponding method, not directly new

2. The significance of the singleton mode: saving system resources

Answer: [A class has only one unique object and provides a global access point], saving system resources. Specific scenarios: such as public global configuration.

The public global configuration needs to load some configurations and properties when the system is running. These configurations and properties must exist and are public. At the same time, they need to exist throughout the life cycle, so only one copy is required. Example mode implementation.

3. Usage scenarios of singleton mode

Answer: Objects that need to be created and destroyed frequently , heavyweight objects that are often used (creating objects takes a lot of time or resources), tool objects, objects that frequently access databases or files (such as data sources, session factories) wait)

4. The way of singleton mode

  • Personally need to master: very simple hungry style (static constant/static code block), lazy style (double check ), static inner class

  • Understand that the recommended patterns for development are hungry man style (static constant/static code block), double check  (improved and practical version of lazy man style),  static inner classenumeration mode

  • When mastering double checks, you can first understand the three situations of lazy people who are not recommended for development (thread unsafe, thread safe [synchronization method], thread safe [synchronous code block])

  • If you write the singleton mode [hungry man, lazy man] in the interview , write the hungry man style (static constant/static code block) and the lazy man style ( double check [the improved practical version of the lazy man style])

5. The singleton mode takes advantage of the characteristics of jvm [in the mode of static inner classes]

■ Advantages and disadvantages of static inner classes: (Using two characteristics of jvm, it plays the role of lazy loading and thread safety)

  • Lazy loading: Take advantage of the characteristics of jvm loading : when the external class is loaded, the internal static class will not be loaded, thus ensuring lazy loading.

  • Thread safety: When the class is being initialized , other threads cannot enter . The static properties of the class will only be initialized when the class is loaded for the first time, ensuring thread safety .


 

1. What is a singleton pattern:

The definition in java is: a class has one and only one instance , [ 单例], and instantiates itself to provide to the entire system.

(1) The singleton mode ensures that there is only one object of this class in the system memory, saving system resources. For some objects that need to be created and destroyed frequently, using the singleton mode can improve system performance

(2) When you want to instantiate a singleton class, you must remember to use the corresponding method of obtaining the object instead of using new

2. Steps to realize singleton:

1. The constructor is private , 防止new,导致多个实例but the object is created inside the class

2. Expose a static public method  getInstance


 

Three, the singleton way

■ There are eight modes of singleton mode:

Hungry Chinese style (static constant/static code block)

Lazy style (thread-unsafe/thread-safe, synchronized methods/thread-safe, synchronized code blocks)

double check

static inner class

enumerate

★ The difference between hungry style and lazy style:

Hungry man style: Create an instance when the class is initialized at the beginning, while the lazy man style is to create an instance when it is needed


 

■ Hungry style (static constant/static code block)

** 在开发中推荐使用,尤其是该类的实例会用到,避免了造成内存的浪费**, if the instance of this class is not used, it will cause a waste of memory.

<span style="color:rgba(0, 0, 0, 0.8)"><span style="background-color:#ffffff"><code><span style="color:#5c6370"><em>/**
* 饿汉式(静态常量)
*/</em></span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> <span style="color:#e6c07b">Singleton</span>{
    <span style="color:#c678dd">private</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">final</span> Singleton singleton  = <span style="color:#c678dd">new</span> Singleton();<span style="color:#5c6370"><em>//饿汉式,初始化时就创建好了实例[使用了final常量-->饿汉式(静态常量)]</em></span>
    
    <span style="color:#c678dd">private</span> <span style="color:#61aeee">Singleton</span>(){}<span style="color:#5c6370"><em>//构造器私有化,防止new,导致多个实例</em></span>
    
    <span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> Singleton <span style="color:#61aeee">getInstance</span>(){<span style="color:#5c6370"><em>//向外暴露一个静态的公共方法  getInstance</em></span>
        <span style="color:#c678dd">return</span> singleton;
    }
}
</code></span></span>
<span style="color:rgba(0, 0, 0, 0.8)"><span style="background-color:#ffffff"><code><span style="color:#5c6370"><em>/**
* 饿汉式(静态代码块)
*/</em></span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> <span style="color:#e6c07b">Singleton</span>{
    <span style="color:#c678dd">private</span> <span style="color:#c678dd">static</span> Singleton singleton  = <span style="color:#c678dd">new</span> Singleton();<span style="color:#5c6370"><em>//饿汉式,初始化时就创建好了实例</em></span>
    
    <span style="color:#5c6370"><em>//代码块[使用了static代码块-->饿汉式(静态代码块)]</em></span>
    <span style="color:#c678dd">static</span>{
        singleton = <span style="color:#c678dd">new</span> Singleton();
    }
    
    <span style="color:#c678dd">private</span> <span style="color:#61aeee">Singleton</span>(){}<span style="color:#5c6370"><em>//构造器私有化,防止new,导致多个实例</em></span>
    
    <span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> Singleton <span style="color:#61aeee">getInstance</span>(){<span style="color:#5c6370"><em>//向外暴露一个静态的公共方法  getInstance</em></span>
        <span style="color:#c678dd">return</span> singleton;
    }
}
</code></span></span>

■ Advantages and disadvantages of Hungarian style (static constant) and Hungarian style (static code block): the same

□ Advantages: Compared with the implementation 简单, the instantiation is completed when the class is loaded,避免了多线程同步问题

□ Disadvantage: The instantiation is completed when the class is loaded (there are many situations for class loading, not necessarily calling the getInstance() method to make the class load), and the effect is not good 没有达到懒加载. If the instance is never used by the program, then造成了空间浪费

■ Lazy style (thread unsafe/thread safe, synchronized methods/thread safe, synchronized code blocks)

□ Lazy style (thread unsafe)

<span style="color:rgba(0, 0, 0, 0.8)"><span style="background-color:#ffffff"><code><span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> <span style="color:#e6c07b">Singleton</span>{
    <span style="color:#c678dd">private</span> <span style="color:#61aeee">Singleton</span>(){}<span style="color:#5c6370"><em>//构造器私有化,防止new,导致多个实例</em></span>
    <span style="color:#c678dd">private</span> <span style="color:#c678dd">static</span> Singleton singleton;
    <span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> Singleton <span style="color:#61aeee">getInstance</span>(){<span style="color:#5c6370"><em>//向外暴露一个静态的公共方法  getInstance</em></span>
        <span style="color:#c678dd">if</span>(singleton == <span style="color:#c678dd">null</span>){
            singleton = <span style="color:#c678dd">new</span> Singleton();
        }
        <span style="color:#c678dd">return</span> singleton;
    }
    
}

</code></span></span>

■ Lazy style (thread unsafe) Advantages and disadvantages: It has the effect of lazy loading, but 只适合在单线程下使用( 开发中不推荐使用)

□ Reason for thread insecurity: If under multi-threading, one thread enters the if (singleton == null) judgment statement block, and the other thread also passes the judgment statement before it has time to execute, then multiple threads will be generated. instances. Therefore, this method cannot be used in a multi-threaded environment

□ Lazy style (thread safety, synchronous method)

<span style="color:rgba(0, 0, 0, 0.8)"><span style="background-color:#ffffff"><code><span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> <span style="color:#e6c07b">Singleton</span>{
    <span style="color:#c678dd">private</span> <span style="color:#61aeee">Singleton</span>(){}<span style="color:#5c6370"><em>//构造器私有化,防止new,导致多个实例</em></span>
    <span style="color:#c678dd">private</span> <span style="color:#c678dd">static</span> Singleton singleton;
    <span style="color:#5c6370"><em>//同步方法,synchronized直接加在方法上</em></span>
    <span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">synchronized</span> Singleton <span style="color:#61aeee">getInstance</span>(){<span style="color:#5c6370"><em>//向外暴露一个静态的公共方法  getInstance</em></span>
        <span style="color:#c678dd">if</span>(singleton == <span style="color:#c678dd">null</span>){
            singleton = <span style="color:#c678dd">new</span> Singleton();
        }
        <span style="color:#c678dd">return</span> singleton;
    }

}
</code></span></span>

■ Lazy style (thread safety, synchronization method) advantages and disadvantages: it has the effect of lazy loading, thread safety, but 调用效率低( 开发中不推荐使用)

□ Lazy style (thread safety, synchronized code blocks)

<span style="color:rgba(0, 0, 0, 0.8)"><span style="background-color:#ffffff"><code><span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> <span style="color:#e6c07b">Singleton</span>{
    <span style="color:#c678dd">private</span> <span style="color:#61aeee">Singleton</span>(){}<span style="color:#5c6370"><em>//构造器私有化,防止new,导致多个实例</em></span>
    <span style="color:#c678dd">private</span> <span style="color:#c678dd">static</span> Singleton singleton;
    <span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> Singleton <span style="color:#61aeee">getInstance</span>(){<span style="color:#5c6370"><em>//向外暴露一个静态的公共方法  getInstance</em></span>
        <span style="color:#c678dd">if</span>(singleton == <span style="color:#c678dd">null</span>){
            <span style="color:#5c6370"><em>//同步代码块,synchronized是单独作为代码块使用</em></span>
            <span style="color:#c678dd">synchronized</span> (Singleton.<span style="color:#c678dd">class</span>){
                singleton = <span style="color:#c678dd">new</span> Singleton();
            }     
        }
        <span style="color:#c678dd">return</span> singleton;
    }
}
</code></span></span>

■ Lazy style (thread safety, synchronous code block) advantages and disadvantages: it has the effect of lazy loading, but 只适合在单线程下使用( 开发中不推荐使用)

□ Thread unsafe reason: Same as □ Lazy style (thread unsafe).

■ double check

<span style="color:rgba(0, 0, 0, 0.8)"><span style="background-color:#ffffff"><code><span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> <span style="color:#e6c07b">Singleton</span>{
    <span style="color:#c678dd">private</span> <span style="color:#61aeee">Singleton</span>(){}<span style="color:#5c6370"><em>//构造器私有化,防止new,导致多个实例</em></span>
    <span style="color:#c678dd">private</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">volatile</span> Singleton singleton;
    <span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> Singleton <span style="color:#61aeee">getInstance</span>(){<span style="color:#5c6370"><em>//向外暴露一个静态的公共方法  getInstance</em></span>
        <span style="color:#5c6370"><em>//第一层检查</em></span>
        <span style="color:#c678dd">if</span>(singleton == <span style="color:#c678dd">null</span>){
            <span style="color:#5c6370"><em>//同步代码块</em></span>
            <span style="color:#c678dd">synchronized</span> (Singleton.<span style="color:#c678dd">class</span>){
                 <span style="color:#5c6370"><em>//第二层检查</em></span>
                <span style="color:#c678dd">if</span>(singleton == <span style="color:#c678dd">null</span>) {
                    singleton = <span style="color:#c678dd">new</span> Singleton();
                }
            }

        }
        <span style="color:#c678dd">return</span> singleton;
    }

}
</code></span></span>

Advantages and disadvantages of double checking: solves the thread safety problem of synchronizing code blocks.

In fact, it is an optimized and improved version of the above □ lazy style (thread safety, synchronized code blocks).

■ static inner class

<span style="color:rgba(0, 0, 0, 0.8)"><span style="background-color:#ffffff"><code><span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> <span style="color:#e6c07b">Singleton</span>{
    <span style="color:#c678dd">private</span> <span style="color:#61aeee">Singleton</span>(){}<span style="color:#5c6370"><em>//构造器私有化,防止new,导致多个实例</em></span>
    <span style="color:#5c6370"><em>//静态内部类,在其内部以静态常量的方式实例化对象</em></span>
    <span style="color:#c678dd">private</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">class</span> <span style="color:#e6c07b">SingletonInstance</span>{
        <span style="color:#c678dd">private</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">final</span> Singleton singleton = <span style="color:#c678dd">new</span> Singleton();<span style="color:#5c6370"><em>//常量静态属性,实例化对象[初始化]</em></span>
    }
    <span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> Singleton <span style="color:#61aeee">getInstance</span>(){<span style="color:#5c6370"><em>//向外暴露一个静态的公共方法  getInstance</em></span>
        <span style="color:#c678dd">return</span> SingletonInstance.singleton;
    }
}
</code></span></span>

■ Advantages and disadvantages of static inner classes: (Using two characteristics of jvm, it plays the role of lazy loading and thread safety)

  • Lazy loading: Take advantage of the characteristics of jvm loading : when the external class is loaded, the internal static class will not be loaded, thus ensuring lazy loading.

  • Thread safety: When the class is being initialized , other threads cannot enter. The static properties of the class will only be initialized when the class is loaded for the first time, ensuring thread safety.

1. When the external class Singleton is loaded, the static internal class SingletonInstance will not be loaded immediately to achieve lazy loading

2. When the external class Singleton calls getInstance(), the static internal class SingletonInstance is only loaded once, and the static constant attribute singleton of the static internal class SingletonInstance is initialized to ensure thread safety.

■ Enumeration method

<span style="color:rgba(0, 0, 0, 0.8)"><span style="background-color:#ffffff"><code><span style="color:#c678dd">enum</span> Singleton{
    INSTANCE;
    <span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61aeee">method</span>(){
<span style="color:#5c6370"><em>//            操作方法</em></span>
    }

}
</code></span></span>

■ Advantages and disadvantages of the enumeration method: thread safety, high efficiency, and 防止反序列化重新创建新的对象.


 

4. Singleton usage scenarios

Objects that need to be created and destroyed frequently,

It takes too much time or resources to create objects (ie: heavyweight objects), but frequently used objects, tool objects, objects that frequently access databases or files (such as data sources, session factories, etc.)

Guess you like

Origin blog.csdn.net/m0_69424697/article/details/125164888