Patrón de diseño simple singleton

Patrón de diseño: singleton "simple"

Resumen

En algunos escenarios, para algunas clases, a menudo solo necesitamos instanciar un objeto. Dicha clase se llama clase singleton. El objeto de instancia creado se llama objeto singleton, como el administrador de tareas en el sistema operativo. Uso de recursos del sistema, si hay varios objetos en este momento, también debe mantener la coherencia de los datos entre varios objetos, pero en su lugar, hacer que el procesamiento del programa sea engorroso. Del mismo modo, hay grupos de subprocesos, cachés, cuadros de diálogo, registros, objetos de controlador de dispositivo, etc. que solo necesitan instanciarse una vez.
Desde la perspectiva de la estructura de clase sola, el patrón singleton puede ser el patrón de diseño más simple, pero aún es un poco más elaborado cuando se trata de los detalles. El diagrama de estructura de clase se muestra en la siguiente figura:
Diagrama de estructura de patrón Singleton

El patrón singleton asegura que las clases singleton se instancian como máximo una vez y proporciona un punto de acceso global.


Lograr

Hambriento

La forma más directa y segura es privatizar el método de construcción, construir un objeto de instancia internamente y proporcionar un método de acceso estático para obtener un objeto singleton. El código de muestra es el siguiente:

package singleton;

public class EagerSingleton {
    private static EagerSingleton instance = new EagerSingleton();

    private EagerSingleton() {
    }

    public static EagerSingleton getInstance() {
        return instance;
    }

}

Se puede ver que el objeto de instancia interna se crea cuando se inicializa la clase, y la clase singleton proporciona un método de acceso estático getInstance () para acceso externo al objeto. La implementación al estilo del hambre también se denomina instanciación ansiosa. Esta implementación es adecuada para escenarios en los que la aplicación siempre accede a objetos de instancia o los objetos no ocupan demasiados recursos cuando se crean y ejecutan.

Perezoso

En consecuencia, en el caso de la instancia instantánea perezosa, solo necesitamos crear una instancia del objeto singleton por primera vez, y luego devolverlo directamente al acceder más tarde, lo que puede evitarlo Para resolver el problema de crear objetos redundantes cuando el sistema no necesita acceder a los objetos. La idea directa de la implementación es la siguiente:

package singleton;

public class LazySingleton {
    private static LazySingleton instance = null;

    private LazySingleton() {
    }

    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

En este momento, el problema que se encuentra en un entorno de subprocesos múltiples es que cuando la sentencia de juicio if se ejecuta al mismo tiempo, se crean múltiples objetos y no se puede garantizar un singleton. Además, considere agregar la palabra clave sincronizada al método para sincronizar la ejecución del método.

package singleton;

public class LazySingleton {
    private static LazySingleton instance = null;

    private LazySingleton() {
    }

    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

Doble control de bloqueo

La palabra clave sincronizada, a la vez que garantiza la sincronización de subprocesos, también aporta ineficiencia en la obtención de instancias de objetos en situaciones de subprocesos múltiples, una mejora adicional: reducir el alcance de los bloques de instrucciones sincronizadas. Si todo el bloque de sentencias de juicio se mantiene sincronizado, cada vez que se adquiere un objeto, debe mantenerse sincronizado, para reducir aún más el alcance de la sincronización, y la implementación del bloqueo de doble verificación se mejora de la siguiente manera:

package singleton;

public class LazySingleton {
    private volatile static LazySingleton instance = null;

    private LazySingleton() {
    }

    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized (LazySingleton.class) {
                if (instance == null) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}

Nota: Los métodos de implementación anteriores tienen el riesgo de llamar al método de construcción privada a través del mecanismo de reflexión. Puede considerar más el criterio de agregar el número de instancias de verificación en el método de construcción privada

Implementación de enumeración

Quizás el método de implementación singleton más simple:

package singleton;

public enum Singleton {
    INSTANCE;
}

Evita de forma concisa el riesgo de múltiples instancias y proporciona un mecanismo de serialización de forma gratuita. "Java efectivo" incluso dice que este método se ha convertido en la mejor manera de lograr Singleton.


Resumen

  1. El patrón singleton garantiza la unicidad de los objetos de clase singleton. Tiene sus escenarios de aplicación específicos. Aunque existen múltiples métodos de implementación, cuando aclaras sus ventajas y desventajas, estos sustantivos ya no te confundirán;
  2. Aunque la estructura del patrón singleton es simple, no es fácil instanciar un objeto, y hay muchos conocimientos básicos involucrados: la garantía de unicidad al serializar, el papel de volátil en la programación de subprocesos múltiples, la limitación de cargadores de clases, etc. , Xiaobian también se está acumulando constantemente.

Referencias

"Patrones de diseño grandes"
" Patrones de diseño de cabeza primero"
"Java efectivo"
"Patrones de diseño Edición Java"
[Cómo escribir patrones singleton correctamente]

PD: Singleton en CSDN

Al momento de escribir este artículo, la aplicación Singleton en CSDN me torturaba severamente. Al usar el editor de rebajas en CSDN para escribir al final del artículo, el mismo navegador comenzó a abrir otra página de edición de rebajas de CSDN. En este momento, la página de edición original se abrió nuevamente y el contenido del borrador previamente no guardado desapareció Ahora ... tengo que reescribirlo / (ㄒ o ㄒ) / ~~ @CSDN, ¿es esto un error? ? ?

Publicado 159 artículos originales · elogiados 225 · 210,000 visitas

Supongo que te gusta

Origin blog.csdn.net/lyg673770712/article/details/79635282
Recomendado
Clasificación