Notas de estudio: modo singleton

Modo singleton: ¿Qué es el modo singleton ? Dim ? ¿Cuándo se usa ? ¿Por qué usarlo? ¿Cómo usarlo? ( Primero ven con una ola de calidad cinco consecutivas )

¿Qué es?

¿Modo singleton? Entendido literalmente, simple: uno, ejemplo: instancia, que es lo que llamamos el objeto

¿Cual es el uso?

Es para la reutilización de recursos, solo necesita ser asignado o inicializado una vez, y todos pueden reutilizarlo.

¿Cuándo se usa? ¿Por qué usarlo? (Solo uno como calendario, solo uno como contenedor IOC)

Oyente de escucha, clase de calendario de calendario, clase de contenedor de IOC, configuración de información de configuración (un movimiento es un singleton), todos estos son singletons

¿Cómo usarlo? (No puedo decir una palabra, déjame hablar de ello con cuidado)

A continuación, usaré el estilo hambriento, el estilo perezoso, el modo singleton más poderoso, enumeración, registro , deserialización, cómo garantizar el singleton y otros modos singleton para explicar en detalle 

 

  1. Estilo chino hambriento (Hay errores obvios que hacen imposible darse cuenta del singleton, la respuesta está oculta en el siguiente texto)

¿Qué es el estilo chino hambriento? Tengo entendido que no puedo esperar a comer cuando tengo hambre. Mira la novena línea de código a continuación, que se declara como

private static final: indica que el objeto se inicializa cuando se carga la clase, y luego estático, por lo que el objeto se mantiene hasta que el programa se detiene

Desventajas: Naturalmente , no importa si usa este objeto o no, lo inicializará al cargar esta clase y ocupará espacio hasta que el programa se detenga.

Ventajas: Obviamente, debido a que se inicializa cuando se carga la clase, no hay problema de concurrencia cuando se crea el objeto, es decir, no hay problema de seguridad de subprocesos, se puede garantizar singleton, y la eficiencia no es mala, porque necesita que se creará cuando se cree el objeto Guarde esos pocos nanosegundos

Escenario de aplicación sugerido: si solo necesita una copia de una determinada clase de objetos y la usa con mucha frecuencia, puede usar este modo

 

  1. Estilo de hombre perezoso (explícitamente, la respuesta está en la imagen de abajo)

¿Cuál es el estilo del hombre perezoso? Tengo entendido que cuando comprende las características de las personas perezosas, no se apresura a prepararse de antemano para nada y solo debe prepararse cuando lo necesite.

Podemos ver que el objeto en el modo diferido se puede obtener llamando al método cuando sea necesario, y puede garantizar el singleton (¿se puede garantizar?) Continuemos analizando las ventajas y desventajas.

Ventajas: evitar el desperdicio de memoria, obtener solo cuando se necesita el objeto y básicamente garantizar el singleton cuando la concurrencia no es alta

Desventajas: Obviamente, lo mencionado anteriormente que se puede garantizar el singleton cuando la concurrencia no es alta, pero no se puede garantizar cierto singleton cuando la concurrencia es alta. Cómo resolverlo, agregue una palabra clave sincronizada al frente del método (si el los requisitos de rendimiento no son altos, puede agregar, después de todo, el bloqueo de sincronización tiene que esperar, si no lo entiende, puede obtener información sobre el bloqueo de sincronización sincronizado)

  1. Dado que hay más o menos deficiencias en lo anterior, aquí hay una versión mejorada de estilo perezoso (es decir, la versión más poderosa del título, no me llames el archivo del título ...)

Ventajas: tanto el problema de uso de memoria del modo de hombre hambriento como el problema de rendimiento sincronizado (he probado el rendimiento, la velocidad de creación de objetos de 200 W es básicamente la misma que en el modo de hombre hambriento), el código de prueba no se publicará, Inténtalo tú mismo

Desventajas: bienvenido a dejar un mensaje

Interés simple registrado

El modo singleton registrado también se denomina modo singleton jerárquico, que consiste en registrar cada instancia en un lugar determinado y utilizar un identificador único para obtener la instancia. Hay dos modos i singleton registrados: uno es el modo singleton enumerado y el otro es el modo singleton contenedor.

1. Modo singleton enumerado

  El modo de enumeración singleton se escribe de la siguiente manera:

Copiar codigo

public enum EnumSingleton {
    INSTANCE;
    private Object data;
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
    public static EnumSingleton getInstance(){
        return INSTANCE;
    }
}

Copiar codigo

  El código de prueba es el siguiente:

Copiar codigo

    @Test
    void EnumSingletonTest(){
        EnumSingleton e1 = null;
        EnumSingleton e2 = EnumSingleton.getInstance();
        e2.setData(new Object());
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("EnumSingleton.obj");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(e2);
            oos.flush();
            oos.close();

            FileInputStream fis = new FileInputStream("EnumSingleton.obj");
            ObjectInputStream ois = new ObjectInputStream(fis);
            e1 = (EnumSingleton)ois.readObject();
            ois.close();
            System.out.println(e1.getData());
            System.out.println(e2.getData());
            System.out.println(e1.getData() == e2.getData());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Copiar codigo

  Los resultados son los siguientes:

  El tipo de enumeración en realidad encuentra un objeto de enumeración único a través del nombre de la clase y el objeto de la clase. Por lo tanto, es imposible que el cargador de clases cargue el objeto de enumeración varias veces.

  Entonces, ¿puede la reflexión destruir el patrón singleton enumerado? El código de prueba es el siguiente:

Copiar codigo

    @Test
     void EnumSingletonTestThread() {
        try{
            Class clazz = EnumSingleton.class;
            Constructor c = clazz.getDeclaredConstructor();
            c.newInstance();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

Copiar codigo

  Los resultados son los siguientes:

 Un error no encontró un método de construcción sin argumentos. Ver el código fuente de Enum Su método de construcción tiene solo un método de construcción de tipo protegido, el código es el siguiente:

  Enum protegido (nombre de cadena, int ordinal) {this.name = nombre; this.ordinal = ordinal; }  

  Vuelva a realizar la siguiente prueba:

Copiar codigo

    @Test
     void EnumSingletonTestThread() {
        try{
            Class clazz = EnumSingleton.class;
            Constructor c = clazz.getDeclaredConstructor(String.class,int.class);
            c.setAccessible(true);
            EnumSingleton enumSingleton = (EnumSingleton)c.newInstance("l-coil",666);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

Copiar codigo

   Los resultados de la prueba son los siguientes:

  

  El error ya es obvio y no se puede utilizar la reflexión para crear un tipo enumerado.

  El modo singleton enumerado es también un tipo de implementación del modo singleton escrito en el libro Effective Java. La naturaleza gramatical especial y la reproducción de la enumeración JDK también acompañan a la cita de enumeración, lo que hace que el modo de enumeración única sea una implementación más elegante. 

2. Contenedor singleton

  El contenedor singleton se escribe de la siguiente manera:

Copiar codigo

public class ContainerSingleton {
    private ContainerSingleton(){}
    private static Map<String,Object> ioc = new ConcurrentHashMap<String,Object>();
    public static Object getBean(String className){
        synchronized (ioc){
            if(!ioc.containsKey(className)){
                Object obj = null;
                try{
                    obj = Class.forName(className).newInstance();
                    ioc.put(className, obj);
                }catch (Exception e){
                    e.printStackTrace();
                }
                return obj;
            } else {
              return ioc.get(className);
            }
        }
    }
}

Copiar codigo

  El modo singleton de estilo contenedor se utiliza en muchos casos, gestión de edición. No es seguro para subprocesos.

Supongo que te gusta

Origin blog.csdn.net/My_SweetXue/article/details/111608549
Recomendado
Clasificación