Singleton pattern

Guarantees that there is only one instance of a class, and provides a global access point to it.

If you want to control that only one instance of a class is created, the first problem is to take back the permission to create an instance, let the class itself be responsible for creating an instance of its own class, and then use this class to provide external methods that can access this class instance, This is how the singleton pattern is implemented.

The structure and implementation of the singleton pattern

Structure diagram of the singleton pattern
Structure diagram of the singleton pattern

Singleton: Responsible for creating its own unique instance of the Singleton class, and provide a getInstance method to access the unique instance of this class externally.

  1. private constructor
  2. Provides a static method for getting an instance
  3. Define the properties that store the instance, because it is to be used in a static method, so add static modification
  4. Create a control instance

sample code

lazy mode

The so-called lazy mode, since it is lazy, don't worry when creating an object instance, it will only be created when the object instance is about to be used, and the object instance will not be created when the object is loaded.

package com.liuhao.designpattern.singleton;

/**
 * 单例模式懒汉模式
 * 
 * @author liuhao
 * 
 *         2015年7月17日
 */
public class SingletonLazy {
    // 4. 定义一个变量来存储创建好的类实例
    // 5. 因为要在静态方法中使用,因此要加上static修饰
    private static SingletonLazy instance = null;

    // 1. 构造方法私有化,好在内部控制创建实例的数目
    private SingletonLazy() {
    }

    // 2. 定义一个方法为客户端提供类实例
    // 3. 这个方法需要定义成类方法,也就是
    public static SingletonLazy getInstance() {
        // 6. 判断存储实例的变量是否有值
        if (instance == null) {
            instance = new SingletonLazy();
        }
        return instance;
    }

    private String singletonData;// 单例可以有自己的属性

    /**
     * 获取属性的值
     * 
     * @return 属性的值
     */
    public String getSingletonData() {
        return singletonData;
    }

    /**
     * 单例可以有自己的操作方法
     */
    public void singletonOperation() {

    }
}

hungry man mode

The so-called hungry mode is that it is more urgent to create an object instance, and an object instance will be created when the class is loaded.

package com.liuhao.designpattern.singleton;

/**
 * 单例模式饿汉模式
 * 
 * @author liuhao
 * 
 *         2015年7月17日
 */
public class SingletonHungry {
    // 4. 直装载类的时候就会创建对象实例,只创建一次
    private static SingletonHungry instance = new SingletonHungry();

    // 1. 构造方法私有化,好在内部控制创建实例的数目
    private SingletonHungry() {
    }

    // 2. 定义一个方法为客户端提供类实例
    // 3. 这个方法需要定义成类方法,也就是
    public static SingletonHungry getInstance() {
        // 5. 直接使用以及创建好的实例
        return instance;
    }

    private String singletonData;// 单例可以有自己的属性

    /**
     * 获取属性的值
     * 
     * @return 属性的值
     */
    public String getSingletonData() {
        return singletonData;
    }

    /**
     * 单例可以有自己的操作方法
     */
    public void singletonOperation() {

    }
}

other

The scope of the singleton pattern

At present, the singleton implemented by Java is in the scope of a virtual machine. Because the function of loading a class is a virtual machine, a virtual machine will create an instance of a class when it loads the hungry Chinese mode through its own ClassLoader to implement a singleton.

Therefore, if there are many ClassLoaders in a virtual machine, and these ClassLoaders all load a certain class, multiple instances will be generated.

The calling sequence of the singleton pattern

  • lazy mode
The calling sequence of the singleton pattern
The calling sequence of the singleton pattern
  • hungry man mode
The calling sequence of the singleton pattern
The calling sequence of the singleton pattern

Some ideas embodied

  • Lazy loading
    In lazy mode, the required resources or data are not loaded at the beginning, and are loaded until they are about to be used, which is the so-called "lazy loading".

  • Cache
    When some resources or data are frequently used and they are stored outside the system (such as database, hard disk), each operation must be obtained from the database, which will be very slow and performance problems.

A simple way is to cache these data in memory, and search for it in memory every time you operate, if there is, use it directly; if not, get it and set it in the cache.

Caching is a typical space-for-time scheme.

thread safety

  1. Lazy mode without synchronization is thread-unsafe. For example, if there are threads A and B calling the getInstance method at the same time, it may cause concurrency problems, as shown in the figure.


    Lazy mode thread conflict
    Lazy mode thread conflict
  2. How to achieve thread safety in lazy mode

    1. Add keywords synchronizedas follows
    public static synchronized SingletonLazy getInstance() {}
    
    1. Double check locking. It is not necessary to synchronize every time you enter getInstance, but to not synchronize first, after entering the method, first check whether the instance exists. If it does not exist before entering the following synchronized block, this is the first check. After entering the synchronized block, check again if the instance exists, if not, create an instance in the case of synchronization, which is the second check.
      The implementation of the double-checked locking mechanism requires the use of volatilekeywords. The value of the variable modified by it will not be cached by the local thread. All reads and writes of the variable are directly operated on the shared memory, thus ensuring that multiple threads can process it correctly. the variable.
      Implementation:
    public static SingletonVolatile getInstance() {
        // 检查实例是否存在,不存在则进入到同步块
        if (instance == null) {
            // 同步块,线程安全地创建实例
            synchronized (SingletonVolatile.class) {
                // 再次检查实例是否存在,不存在则真正的创建实例
                if (instance == null) {
                    instance = new SingletonVolatile();
                }
            }
        }
        return instance;
    }
    

    This implementation achieves thread safety without compromising performance too much.

  3. Hungry mode is thread-safe.


Author: hoxis
Link: https://www.jianshu.com/p/24d2e6d9af3e
Source: Jianshu
Copyright belongs to the author. For commercial reprints, please contact the author for authorization, and for non-commercial reprints, please indicate the source.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326392829&siteId=291194637