Design mode study notes --- 3. Single case mode

  • The singleton pattern (Singleton Pattern) is one of the simplest design patterns in Java. This type of design pattern is a creational pattern that provides the best way for common objects.
  • This pattern involves a single class, which is responsible for creating its own objects, while ensuring that only a single object is created. This class provides a way to access its only objects, which can be accessed directly without instantiating objects of this class;

  • note:

    • 1. A singleton class can only have one instance;

    • 2. The singleton class must create its own unique instance;

    • 3. The singleton class must provide this instance to all other objects;

  • Intent: To ensure that there is only one instance of a class, and to provide a global access point to access it;

  • Main solution: a globally used class is frequently created and destroyed;

  • When to use: When you want to control instance trees and save system resources;

  • How to solve: judge whether the system already has this singleton, return if there is, create if not;

  • Key code: The constructor is private;

  • Applications:

    • 1. There is only one teacher in a class;

    • 2. WIndows is multi-process and multi-thread. When operating a file, it is inevitable that multiple processes or threads operate on a file at the same time, so all files must be processed through a unique instance;

    • 3. Some device managers are often designed in singleton mode, for example, a computer has two printers, and it is necessary to deal with the problem that two printers cannot print the same file when outputting;

  • advantage:

    • 1. There is only one instance in memory to reduce memory overhead, especially frequent creation and destruction of instances (such as WEB page cache);

    • 2. Avoid multiple possession of resources (such as file writing operations);

  • Disadvantages: There is no excuse, it cannot be inherited, and it conflicts with the principle of single responsibility. A class should only care about internal logic, not how it is instantiated outside;

  • scenes to be used:

    • 1. Require the production of a unique serial number;

    • 2. The counter in WEB does not need to be added to the database every time it is refreshed, and it is cached first with a single case;

    • 3. To create an object consumes too many resources, such as the connection of I / O to the database, etc .;

    • Note: The getInstance () method needs to use synchronized lock synchronized (Singleton.class) to prevent multiple threads from entering at the same time and causing the Instance to be instantiated multiple times;

  • Actual combat:

    • We will create a SingleObject class. The SingleObject class has its private constructor and a static instance of itself;

    • The SingleObject class provides a static method for the outside world to obtain its static instance.

 

package singleton;

/**
 * @author yangxin_ryan
 */
public class SingleObject {
    // Create singleObject Object
    private static SingleObject instance = new SingleObject();
    // make construct private avoid instatiation
    private SingleObject(){}

    public static SingleObject getInstance(){
        return instance;
    }

    public void showMessage() {
        System.out.println("Hello World!");
    }
}
package singleton;

/**
 * @author yangxin_ryan
 */
public class SingletonPatternDemo {

    public static void main(String[] args) {
        SingleObject object = SingleObject.getInstance();
        object.showMessage();
    }
}
  • The remaining implementation versions
package singleton;

/**
 * @author yangxin_ryan
 * 懒汉式,线程不安全
 * 这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程,因为没有加锁synchronized,所以严格意义上并不算单例模式;
 */
public class SingletObject1 {

    private static SingletObject1 instance;

    private SingletObject1() {}

    public static SingletObject1 getInstance(){
        if (instance == null) {
            instance = new SingletObject1();
        }
        return instance;
    }
}
package singleton;

/**
 * @author yangxin_ryan
 * 懒汉式,线程安全
 * 这种方式具备很好的lazy loading,能够在多线程中很好的工作,但是效率很低,99%情况下不需要同步;
 */
public class SingletObject2 {

    private static SingletObject2 instance;

    private SingletObject2() {}

    public static synchronized SingletObject2 getInstance(){
        if (instance == null) {
            instance = new SingletObject2();
        }
        return instance;
    }
}
package singleton;

/**
 * @author yangxin_ryan
 * 饿汉式,线程安全
 * 这种方式比较常见,但容易产生垃圾对象。它基于classloader机制避免了多线程的同步,不过instance在类装载时就实例化,
 * 虽然导致类装载的原因有很多,在单例模式中大多数都是调用getInstance方法,但是也不能确定有其他的方式(或者其他静态方法)导致类加载。
 * 这时候初始化intance显然没有达到lazy loading效果
 */
public class SingletObject3 {

    private static SingletObject3 instance = new SingletObject3();
    private SingletObject3(){}
    public static SingletObject3 getInstance(){
        return instance;
    }
}
package singleton;

/**
 * @author yangxin_ryan
 * 双检索/双重校验锁,线程安全
 * 这种方式采用双锁机制,安全且在多线程情况下能保持高性能
 */
public class SingletObject4 {

    private volatile static SingletObject4 singleton;
    private SingletObject4(){}
    public static SingletObject4 getInstance() {
        if (singleton == null) {
            synchronized (SingletObject4.class) {
                if (singleton == null) {
                    singleton = new SingletObject4();
                }
            }
        }
        return singleton;
    }
}

 

Published 1980 original articles · praised 708 · 3.66 million views +

Guess you like

Origin blog.csdn.net/u012965373/article/details/105587679