Singleton proper use

This time we talk about sharing the use of single-case model, in fact, in this public number of design patterns is the first to share Singleton, why should a discussion of singleton? The main article is talking about relatively shallow, only the main idea of ​​the Singleton pattern to do a share, this article will be many ways to share the use of singletons, following entered.

Java programs use to do a small partner know a single case, especially with spring framework to do the project, we all know that spring framework default management class are singletons and thread-safe. Well, if only to ensure that a class is initialized once and thread-safe? With this issue we began this article.

When new to design patterns that most people first come into contact with the first design pattern Singleton pattern is, of course, most people only stay in Singleton, usually with very little in the development of this articles will help you understand the many ways singleton, more text code, if for the singleton pattern concept is not very clear a small partners can see another article, "design patterns singleton pattern."

1. lazy mode

com.study.concurrency.base_concurrency.example.singleton Package; 

/ ** 
 * <P> the Title: Singleton01 </ p> 
 * <P> the Description: lazy mode singleton instance created </ p> In the first use 
 * <the p-> Company: http://www.yinjiedu.com </ the p-> 
 * <the p-> Project: Concurrency </ the p-> 
 * 
 * @author: Qiwei 
 * @date: 2019/8/20 22:41 
 * @ Version: 1.0 
 * / 
public class Singleton01 { 

    Private Singleton01 () { 

    } 

    // singleton object 
    Private static instance Singleton01 = null; 

    / ** 
     * @description: static factory method 
     * @auther: Qiwei 
     * @date: 2019/8 / 20 22:43 
     * @return:Singleton01 
     * /
    public static Singleton01 getInstance() {
        if (instance == null) {
            instance = new Singleton01();
        }
        return instance;
    }
}

In the single-threaded code above is no problem, but in the case of multiple threads is thread-safe code problems mainly in the following code:

2. starving mode

In order to solve the above problems lazy thread-safe mode, we can create a class instance hungry man mode. Starving singleton instance of the pattern is created when the class is loaded, as follows:

package com.study.concurrency.base_concurrency.example.singleton;

/**
 * <p>Title: Singleton02</p >
 * <p>Description: 饿汉模式</p >
 * <p>Company: http://www.yinjiedu.com</p >
 * <p>Project: concurrency</p >
 *
 * @author: qiwei
 * @Date: 2019/8/20 22:53
 * @Version: 1.0
 */
public class Singleton02 {

    private Singleton02() {
    }

    //单例对象
    private static Singleton02 instance = new Singleton02();

    /**
     * @description: 静态的工厂方法
     * @auther: qiwei
     * @date: 2019/8/20 22:55
     * @return: Singleton02
     */
    public static Singleton02 getInstance() {
        return instance;
    }
}

Starving mode issues :

Although hungry man is thread-safe mode, but in the actual development, there will be some issues we need to note.

The first point: starving class loading when the pattern is created on, if the class constructor which a lot of complex processing, class loading will be relatively slow, influence the performance procedures;

The second point: to create a model example of a hungry man, there's no use no matter elsewhere in the project, instance of the class has been created, if not used, will cause waste of resources.

Based on the above, we use the time pattern of starving to note the actual usage scenarios.

3. lazy thread-safe mode of

We see that when you create instances using lazy mode is not thread-safe, here the way we use synchronization lock, so lazy mode is also thread-safe code is as follows:

package com.study.concurrency.base_concurrency.example.singleton;

/**
 * <p>Title: Singleton01</p >
 * <p>Description: 懒汉模式 </p >
 * <p>Company: http://www.yinjiedu.com</p >
 * <p>Project: concurrency</p >
 *
 * @author: qiwei
 * @Date: 2019/8/20 22:41
 * @Version: 1.0
 */
public class Singleton03 {

    private Singleton03() {

    }

    //单例对象
    private static Singleton03 instance = null;

    /**
     * @description: 静态的工厂方法
     * @auther: qiwei
     * @date: 2019/8/20 22:43
     * @return: Singleton01
     */
    public static synchronized Singleton03 getInstance() {
        if (instance == null) {
            instance = new Singleton03();
        }
        return instance;
    }
}

Here we use the synchronized keyword to ensure that the thread-safe, but do not write in the actual development, will bring more serious because synchronized performance overhead.

4. The dual mode of lazy synchronization lock mode (thread safe)

Single-use embodiment the double synchronization lock mode, as follows:

package com.study.concurrency.base_concurrency.example.singleton;

/**
 * <p>Title: Singleton01</p >
 * <p>Description: 懒汉模式 </p >
 * <p>Company: http://www.yinjiedu.com</p >
 * <p>Project: concurrency</p >
 *
 * @author: qiwei
 * @Date: 2019/8/20 22:41
 * @Version: 1.0
 */
public class Singleton04 {

    private Singleton04() {

    }

    //单例对象
    private static Singleton04 instance = null;

    /**
     * @description: 静态的工厂方法
     * @auther: qiwei
     * @date: 2019/8/20 22:43
     * @return: Singleton01
     */
    public static  Singleton04 getInstance() {
        if (instance == null) {
            synchronized (Singleton04.class) {
                if (instance == null) {
                    instance = new Singleton04();
                }
            }
        }
        return instance;
    }
}

In the above code here enabled synchronized double detection mechanism, but such an approach in multiple threads is thread safe, the reason is in the JVM and CPU instruction rearrangement ; here is a brief look at what the computer command:

When Java instantiate an object, mainly through the following three-step instructions:

The first step: allocating memory space objects

The second step: initialize the object

Step 3: Set instance just point to memory allocation

Know the steps above, we know that the event in case of multi-threaded instruction reordering, there will be security problems, such as the above step 123 becomes 132 .

5. The dual mode of lazy synchronization lock mode (thread-safe)

Create a singleton thread safe also use the fourth way, in order to make the fourth example thread-safe, we need to use a keyword: volatile.

code show as below:

package com.study.concurrency.base_concurrency.example.singleton;

/**
 * <p>Title: Singleton01</p >
 * <p>Description: 懒汉模式 </p >
 * <p>Company: http://www.yinjiedu.com</p >
 * <p>Project: concurrency</p >
 *
 * @author: qiwei
 * @Date: 2019/8/20 22:41
 * @Version: 1.0
 */
public class Singleton05 {

    private Singleton05() {

    }

    //单例对象
    private volatile static Singleton05 instance = null;

    /**
     * @description: 静态的工厂方法
     * @auther: qiwei
     * @date: 2019/8/20 22:43
     * @return: Singleton01
     */
    public static Singleton05 getInstance() {
        if (instance == null) {
            synchronized (Singleton05.class) {
                if (instance == null) {
                    instance = new Singleton05();
                }
            }
        }
        return instance;
    }
}

volatile can disable command rearrangement, so the above method is thread-safe. volatile usage scenarios are: the state of the labeled amount, dual detection.

6. starving mode static domain implementation of the (erroneous wording)

Starving mode first implementation uses direct initialization mode, where we can use to achieve a static field, which is in the normal development of the more common way, but there is a pit, to bury to you, as follows:

package com.study.concurrency.base_concurrency.example.singleton;

/**
 * <p>Title: Singleton02</p >
 * <p>Description: 饿汉模式</p >
 * <p>Company: http://www.yinjiedu.com</p >
 * <p>Project: concurrency</p >
 *
 * @author: qiwei
 * @Date: 2019/8/20 22:53
 * @Version: 1.0
 */
public class Singleton06 {

    private Singleton06() {

    }

    static {
        instance = new Singleton06();
    }
    //单例对象
    private static Singleton06 instance = null;

    /**
     * @description: 静态的工厂方法
     * @auther: qiwei
     * @date: 2019/8/20 22:55
     * @return: Singleton02
     */
    public static Singleton06 getInstance() {
        return instance;
    }
}

Singleton pattern above the static fields is problematic, we think there is a problem, we discuss in the end, you can also look for the debug problems.

7. The enumeration singleton pattern of creation

Create a single focus in front of the example embodiment, we touch lazy mode, hungry man mode. Personally I think either lazy mode or starving mode, not the best solution, I recommend using enumeration class to create a single case, both to ensure the thread safety requirements, but also to ensure that the resources are not wasted. Code is implemented as follows:

package com.study.concurrency.base_concurrency.example.singleton;

/**
 * <p>Title: Singleton01</p >
 * <p>Description: 枚举模式 </p >
 * <p>Company: http://www.yinjiedu.com</p >
 * <p>Project: concurrency</p >
 *
 * @author: qiwei
 * @Date: 2019/8/20 22:41
 * @Version: 1.0
 */
public class Singleton07 {

    //私有构造函数
    private Singleton07() {

    }

    //单例对象
    private static Singleton07 instance = null;


    public static Singleton07 getInstance() {
        return Singleton.INSTANCE.getInstance();
    }

    private enum Singleton {
        INSTANCE;

        private Singleton07 singleton;

        Singleton() {
            singleton = new Singleton07();
        }

        public Singleton07 getInstance() {
            return singleton;
        }
    }
}

The above code, when using enumeration constructor JVM guarantee absolute call this method only once, personal recommendation to create a single example of this pattern.

Solve 6: starving mode of static domain implementation issues

Sixth starving mode to create a single way of example, mainly because of problems caused by the position of the code, the correct wording of the code is to exchange the following two positions:

private static Singleton06 instance = null;
static {
    instance = new Singleton06();
}

This is the wrong time of the static fields especially easy to make, I hope you pay attention.

Share on Singleton pattern on here, the inadequacies of hope that we put forward, I will promptly corrected.

  Get real-time information, public concern number: "Programming Art", a two-dimensional code:

  

  

  

  

  

  

  

Guess you like

Origin www.cnblogs.com/winqi/p/11402986.html