I walk very slowly, but I never walk backwards 
Copy the code

Design Pattern – Singleton Pattern (PART 1)


Become as

Hello, everyone ~, I am silent, this class, we officially enter the design mode of learning, the first to talk about is our most common, but also the interview frequency of singleton mode, that old rules, we directly set out

Five heavy state

Before that, let’s have a chat, because some friends ask a question, how is it to learn or master the design pattern? That let’s talk about this topic, there will be a lot of people say that in fact this is not good to define, but if they usually write code, unconscious, use the design patterns, into the actual problems, will soon be able to compare options, use the appropriate design patterns, low coupling, the reasonable solving actual problems, I think is a very good control, Someone on the Internet shared the five realms of design pattern, feel very appropriate, here to share with you


Level 1: New to programming, what are design patterns you’ve heard of but don’t understand

Level 2: I have long programming experience, and I have written a lot of code, which uses design patterns, but I don’t know it

Level 3: You’ve studied design patterns, found that you already use them, and found some new patterns that are useful

Level 4: READ a lot of source code and frameworks written by others, see the design pattern, can appreciate the subtlety of the design pattern and bring benefits

Level 5: You write code without realizing you’re using design patterns, and you write it out

q&a

At the same time, I also need to emphasize one sentence at the beginning, because many friends have said or had such a question in their mind: This can ah, why not so complex, we should pay attention to, design mode is not only standing in the realization of the function of the point of view, but based on the design of the whole software system, so we should learn to learn in the process of learning, summary and contrast thinking, can achieve twice the result with half the effort

The official definition of

The singleton design pattern of classes is to take certain methods to ensure that only one object instance of a class can exist in the entire software system and that the class provides only one method to obtain its object instance (static method).


For the most common example, beans in Spring default to the singleton pattern, where each bean definition generates only one object instance, which is obtained for each getBean request

There are eight methods for singleton mode

So let’s talk about eight implementations of the singleton pattern, as shown below

Hungry (static constant)

Hungry (static code block)

Lazy (thread unsafe)

Lazy (thread-safe, synchronous approach)

Lazy (thread-safe, synchronized code blocks)

Double check

Static inner class

Enumeration methods

Hungry (static constant)

The static constant of hanky-hanky is written as follows:

Constructor privatized (prevents external object instance creation via new + constructor)

Create a final, static instance of a class.

Expose a public static method that returns a unique object instance of that class.

// Static variable
class Singleton{
    // Privatize a constructor
    private Singleton(a){}// Create objects inside the class
    private final static Singleton singleton = new Singleton();

    // Provide public, static methods externally
    public static Singleton getInstance(a){

            returnsingleton; }}public class SingletonDemo {
    public static void main(String[] args) {

        / / test
        Singleton instance = Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        System.out.println(instance == instance1);
        // If the result is true, it is the same instance object}}Copy the code
Written analysis

advantage

This is simpler because instantiation is done at class load time, avoiding thread synchronization issues

However, instance is instantiated when the class is loaded. In singleton mode, most instances call getInstance. However, there are many reasons for class loading. There is no other way (or static way) to load the class, so instance initialization is not lazy

disadvantage

Instantiation is done when the class is loaded, rather than being Lazy, which would waste memory if the instance was never used at all

Hungry (static code block)

The hanky-hank (static code block) approach is to create a singleton object in a static code block, as shown in the figure below

// Static code block
class Singleton{

    private Singleton(a){}private final static Singleton singleton;

    static {
        singleton = new Singleton();
    }

    public static Singleton getInstance(a){

        returnsingleton; }}public class Singletondemo02 {

    public static void main(String[] args) { Singleton instance = Singleton.getInstance(); Singleton instance1 = Singleton.getInstance(); System.out.println(instance == instance1); }}Copy the code
Written analysis

This way is similar to the above, but the class instantiation process is placed in the static code block, is also at the time of class loading, the implementation of the code in the static code block, initialization of the instance of the class, advantages and disadvantages and the first method is consistent, writing method available, but may cause a waste of memory

There are no thread safety issues with hangry

Lazy (thread unsafe)

The lazy version differs from the hungry version in that the object is not created first, but only when the corresponding getInstance() method is called, as shown in the example below

// thread is not safe
class Singleton{
    
    // Privatize the constructor
    private Singleton(a){}// Create objects inside the class
    private static Singleton singleton;

    // Provide a static public method that creates instance only when it is used
    public static Singleton getInstance(a){

        fiif (singleton == null){
            singleton = new Singleton();
        }
        returnsingleton; }}public class SingletonDemo {
    public static void main(String[] args) { Singleton instance = Singleton.getInstance(); Singleton instance1 = Singleton.getInstance(); System.out.println(instance == instance1); }}Copy the code
Written analysis

advantage

The instance is created by calling getInstance() when the instance is used

disadvantage

It can only be used in a single thread, which may cause thread insecurity

If (singleton == null){if (singleton == null){… } judge statement block, before there is time to execute down, another thread to judge, at this time the instance has not yet created, also passed the judgment statement, then there will be multiple instances, thread unsafe problem

Therefore, in real development, this approach is not recommended

Lazy (synchronous method)

To solve the problem of thread insecurity above, we add synchronization to lazy code, the first is the synchronization method, the relevant code is as follows

// lazy synchronization method
class Singleton{

    // Privatize the constructor
    private Singleton(a){}// Create objects inside the class
    public static Singleton singleton;

    // Provide public static methods with synchronous processing
    public static synchronized Singleton getInstance(a){

        if (singleton == null){
            singleton = new Singleton();  
        }
        returnsingleton; }}public class SingletonDemo02 {
    public static void main(String[] args) { Singleton instance = Singleton.getInstance(); Singleton instance1 = Singleton.getInstance(); System.out.println(instance == instance1); }}Copy the code
Written analysis

First of all, it solves the problem of thread insecurity by adding synchronization

Each thread that wants to get an instance of the class needs to perform a synchronization on the getInstance() method, which only executes the instantiation code once. If the thread wants to get an instance of the class, it simply returns

Therefore, this approach is not recommended in real development

Lazy (synchronized code blocks)

Since methods are very inefficient to synchronize, can we use synchronized code blocks? Take a look at the following example code

class Singleton{

    // Privatize the constructor
    private Singleton(a){}// Create objects inside the class
    public static Singleton singleton;

    // Provide public static methods externally
    public static Singleton getInstance(a){

        if (singleton == null) {synchronized (Singleton.class){
                singleton = newSingleton(); }}returnsingleton; }}Copy the code
Written analysis

So this is an improvement on the fourth implementation, synchronizing when you create instance objects, so think about it, is that possible? It’s thread safe


If (singleton == null){if (singleton == null){… } judge statement block, before there is time to execute down, another thread to judge, at this time the instance has not yet created, but also through the statement, it will generate multiple instances, so inside the creation of instance object, synchronization has no practical significance, in the actual development, can not use this way

Next day forecast

OK, due to the space limit, this section will first come here, in the next section, we went on to talk of the singleton pattern after the three types of writing, including double check mechanism, static inner classes, enumerations, at the same time will take you to see the JDK source code, the application of singleton pattern and the matters needing attention of singleton pattern was summarized, and finally, hope everyone in the process of learning, We’ll see you next time