Notas de estudio del modo de diseño --- 3. Modo de caso único

  • El patrón singleton (Patrón Singleton) es uno de los patrones de diseño más simples en Java. Este tipo de patrón de diseño es un patrón de creación que proporciona la mejor manera para objetos comunes.
  • Este patrón involucra una sola clase, que es responsable de crear sus propios objetos, al tiempo que garantiza que solo se cree un único objeto. Esta clase proporciona una forma de acceder a sus únicos objetos, a los que se puede acceder directamente sin crear instancias de objetos de esta clase;

  • Nota:

    • 1. Una clase singleton solo puede tener una instancia;

    • 2. La clase singleton debe crear su propia instancia única;

    • 3. La clase singleton debe proporcionar esta instancia a todos los demás objetos;

  • Intención: garantizar que solo haya una instancia de una clase y proporcionar un punto de acceso global para acceder a ella;

  • Solución principal: una clase utilizada globalmente se crea y destruye con frecuencia;

  • Cuándo utilizarlo: cuándo desea controlar árboles de instancias y guardar recursos del sistema;

  • Cómo resolver: juzgue si el sistema ya tiene este singleton, devuelva si lo hay, cree si no;

  • Código clave: el constructor es privado;

  • Ejemplos de aplicación:

    • 1. Solo hay un maestro en una clase;

    • 2. Windows es multiproceso y multiproceso. Cuando se opera un archivo, es inevitable que múltiples procesos o subprocesos operen en un archivo al mismo tiempo, por lo que todos los archivos deben procesarse a través de una instancia única;

    • 3. Algunos administradores de dispositivos a menudo están diseñados en modo singleton, por ejemplo, una computadora tiene dos impresoras, y es necesario resolver el problema de que dos impresoras no pueden imprimir el mismo archivo al imprimir;

  • Ventajas:

    • 1. Solo hay una instancia en la memoria para reducir la sobrecarga de memoria, especialmente la creación y destrucción frecuente de instancias (como el caché de la página WEB);

    • 2. Evite la posesión múltiple de recursos (como operaciones de escritura de archivos);

  • Desventajas: no hay excusa, no se puede heredar y entra en conflicto con el principio de responsabilidad única. Una clase solo debe preocuparse por la lógica interna, no por cómo se instancia fuera;

  • Escenario de uso:

    • 1. Requerir la producción de un número de serie único;

    • 2. El contador en WEB no necesita agregarse a la base de datos cada vez que se actualiza, y primero se almacena en caché con un solo caso;

    • 3. Crear un objeto consume demasiados recursos, como la conexión de E / S a la base de datos, etc.

    • Nota: El método getInstance () necesita usar el bloqueo sincronizado sincronizado (Singleton.class) para evitar que ingresen varios subprocesos al mismo tiempo y que la instancia se instancia varias veces;

  • Combate real:

    • Crearemos una clase SingleObject. La clase SingleObject tiene su constructor privado y una instancia estática de sí misma;

    • La clase SingleObject proporciona un método estático para que el mundo exterior obtenga su instancia estática.

 

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();
    }
}
  • Las versiones de implementación restantes
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;
    }
}

 

Artículos originales publicados en 1980 · elogiados 708 · 3.66 millones de visitas +

Supongo que te gusta

Origin blog.csdn.net/u012965373/article/details/105587679
Recomendado
Clasificación