[Demostrar cuestiones de seguridad ofrecen la cara] [2 implementa el patrón Singleton - siete tipos de implementaciones]

"Demostrar Oferta de seguridad" Lista


I. Glosario

Singleton (Patrón Singleton) es uno de los más fáciles en los patrones de diseño Java. Este tipo de patrón de diseño pertenece crear esquema, que ofrece la mejor manera de crear objetos. Este modelo implica una sola clase que se encarga de crear sus propios objetos, al tiempo que garantiza que sólo se crea un único objeto. Esta clase proporciona la única forma de acceder al objeto tenga acceso directo, sin instancia de la clase de objeto.

nota:

  • 1, sólo instancia de clase uno singleton.
  • 2, clase Singleton debe crear su propia instancia única.
  • 3, clase singleton debe proporcionar este ejemplo para todos los demás objetos.

Varios realización implementación dos monomodo

La diferencia fundamental entre el hombre perezoso con un hombre hambriento en el estilo y crear sus propios objetos en el exterior ya sea en clase. Y la necesidad de declarar un objeto de la privatización, el constructor debe ser privatizada esta manera no sólo a través de un nuevo acceso objeto externo. palabras de estilo chino son declarar hambre y crear un objeto (porque tenía hambre), el estilo perezoso, entonces simplemente declarar un objeto, llamando a la clase getInstance () método será nuevos objetos.

  1, estilo perezoso, seguro hilo 

  Descripción: Esta es la forma más básica de ejecución, que logró el mayor problema no es el soporte multi-threading. Debido a que no hay bloqueo sincronizado, por lo que en sentido estricto no es un producto único. Obviamente esta manera la carga diferida, no requiere seguro para subprocesos, puede no funcionar en multi-hilo correctamente.

public static class Singleton02{
		private static Singleton02 instance= null;
		
		private Singleton02() {
			
		}
		
		public static Singleton02 getInstance() {
			if(singLeton == null) {
				instance= new Singleton02();
			}
			
			return instance;
		}
	}

2, estilo perezoso, thread-safe

          Descripción: de esta manera tiene una buena carga diferida, puede funcionar bien en multi-hilo, sin embargo, es muy baja eficiencia, el 99% de los casos no requiere sincronización.
         Pros: La primera llamada fue inicializado, para evitar el desperdicio de memoria.
         Contras: debe bloquearse sincronizados para asegurar un solo caso, pero la cerradura afectará a la eficacia. Rendimiento getInstance () la aplicación no es crítica (que utilizan con menos frecuencia).

public static class Singleton03{
		private static Singleton03 instance= null;
		
		private Singleton03() {
			
		}
		
		public static synchronized  Singleton03 getInstance() {
			if(singLeton == null) {
				instance= new Singleton03();
			}
			return instance;
		}
	}

3, hambriento de estilo chino flujos seguros

Descripción: De esta manera utiliza comúnmente, pero objetos de basura propensa.
           Ventajas: no bloqueado, la eficiencia mejorará.
           Desventajas: inicializa cuando se carga la clase, perdiendo la memoria.
           mecanismo cargador de clases Se basa evita la multihilo problema de sincronización, sin embargo, instancia a instancia de la clase se carga en el momento, aunque hay causas carga de clases son muchas, la mayoría de ellos en el modo de singleton están llamando método getInstance, pero no se puede determinar hay otras maneras (u otros métodos estáticos) conduce el cargador de clases, que al parecer no alcanzan inicialización de instancia efecto de carga diferida.

public static class Singleton01{
		private static final Singleton01 INSTACNE= new Singleton01();
		
		private Singleton01() {
			
		}
		
		public static  Singleton01 getInstance() {
			return INSTACNE;
		}
	}

4, detección de bloqueo doble / bloqueo de comprobación doble (la DCL, es decir, cierre de doble marcado) JDK1.5 de, de tipo perezoso thread-safe

Descripción: Este mecanismo de doble modo de bloqueo, y en múltiples hilos de seguridad pueden mantener un alto rendimiento. Rendimiento getInstance () es fundamental para la aplicación.

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

5, las clases internas estáticas , estilo perezoso, thread-safe

Descripción: de esta manera se puede lograr el mismo efecto de retención doble el modo de bloqueo, pero la implementación es más sencilla. Inicialización del campo estático utilizando un retardo, este modo se debe utilizar en lugar del modo de detección de bloqueo doble. Esta forma de realización se aplica sólo al campo estático, el modo de detección de bloqueo doble se puede utilizar cuando un retraso necesario inicializar campos de instancia.
          De esta manera el uso de los mismos mecanismos de cargador de clases para asegurar que sólo un hilo a la inicialización de instancia, es ahora la tercera formas son diferentes: Las tres primeras formas siempre que se carga la clase Singleton, la instancia se crea una instancia (no alcanzaron la carga diferida efecto), pero este enfoque está siendo cargado clase Singleton, instancia no se puede inicializar. Debido a que la clase SingletonHolder no se utiliza activamente, sólo a través de llamada al método getInstance explícita se carga de forma explícita la clase SingletonHolder a instancia instantiate. Imagínese, si usted instancia instancia es que consume muchos recursos, por lo que quiere que se carga demora, por el contrario, no quieren cargar cuando la clase se instancia Singleton, clase Singleton porque no pueden garantizar que la iniciativa también se puede utilizar en otros lugares con el fin de cargada, esta vez a la instancia instantiate claramente inapropiado. Esta vez, de esta manera en comparación con los tres primeros tipos de formas que es muy razonable.

public static class Singleton05{
		private static final class SingletonHold{
			private static final Singleton05 INSTANCE= new Singleton05();
		}
		private Singleton05() {
			
		}
		
		public static Singleton05 getInstance() {
			return SingletonHold.INSTANCE;
		}
	}

6, enumeración , estilo después de morir de hambre, JDK1.5 thread-safe

Descripción: Esta aplicación no ha sido ampliamente adoptado, pero esta es la mejor manera de lograr la modalidad de un solo modo. Es más compacto, mecanismo de soporte de serialización automática para evitar varias instancias de la absoluta.
           Este enfoque es defendido Effective Java autor manera Josh Bloch, que no sólo puede evitar problemas de sincronización multi-hilo, pero también es compatible de forma automática mecanismo de serialización para evitar deserialización volver a crear un objeto nuevo, absolutamente a prevenir múltiples instancias. Sin embargo, sólo se unió a las propiedades de enumeración después JDK1.5, escribir de esta manera no puede dejar de sentir extraña, en la práctica, rara vez se utiliza. No por la reflexión atacar a llamar al constructor privado.

	public enum Singleton06{
		INSTANCE;
		
		public void whateverMethod() {
			
		}
	}

7, bloques estáticos , fórmula de hambre

Descripción: Crear una variable de clase, se creará una instancia del bloque estático. Desde un bloque estático de código se ha ejecutado antes de la utilización de la clase, esta función se puede implementar usando un único modo de realización. En frente de la manera tercera es utilizar variables estáticas para crear una única instancia.

	public static class Singleton04{
		
		private static Singleton04 instance= null;
		
		static {
			instance= new Singleton04();
		}
		
		private Singleton04() {
			
		}
		
		public static Singleton04 getInstance() {
			return instance;
		}
	}

En tercer lugar, las pruebas de código

package com.acm.firstmonth;

import com.acm.firstmonth.SingLeton.Singleton01;
import com.acm.firstmonth.SingLeton.Singleton02;
import com.acm.firstmonth.SingLeton.Singleton03;
import com.acm.firstmonth.SingLeton.Singleton04;
import com.acm.firstmonth.SingLeton.Singleton05;
import com.acm.firstmonth.SingLeton.Singleton06;
import com.acm.firstmonth.SingLeton.Singleton07;

public class Test02 {
	/**
	 * 饿汉式 线程安全  
	 * @author zc
	 *
	 */
	public static class Singleton01{
		private static final Singleton01 INSTANCE = new Singleton01();
		
		private Singleton01() {}
		
		public static Singleton01 getInstance() {
			return INSTANCE;
		}
	}
	/**
	 * 饿汉式 线程安全
	 * @author zc
	 *
	 */
	public static class Singleton02{
		private static Singleton02 instance ;
		static {
			instance = new Singleton02();
		}
		
		private Singleton02() {}
		
		public static Singleton02 getInstance() {
			return instance;
		}
	}
	/**
	 * 饿汉式  线程安全  JDK1.5+
	 * @author zc
	 *
	 */
	public enum Singleton03{
		INSTANCE;
		
		public void whateverMethod() {}
	}
	/**
	 * 懒汉式 线程不安全
	 * @author zc
	 *
	 */
	public static class Singleton04{
		private static Singleton04 instance = null;
		
		private Singleton04() {}
		
		
		public static Singleton04 getInstance() {
			if(instance == null) {
				return instance = new Singleton04();
			}
			return instance;
		}
	}
	/**
	 * 懒汉式 线程安全
	 * @author zc
	 *
	 */
	public static class Singleton05{
		private static Singleton05 instance = null;
		
		private Singleton05() {}
		
		public static synchronized Singleton05 getInstance() {
			if(instance == null) {
				instance = new Singleton05();
			}
			return instance;
		}
	}
	/**
	 * 静态内部类 线程安全  懒汉式
	 * @author zc
	 *
	 */
	public static class Singleton06{
		
		private static class SingletonHold{
			private static final Singleton06 INSTANCE = new Singleton06();
		}
		
		private Singleton06() {}
		
		public static Singleton06 getInstance() {
			return SingletonHold.INSTANCE;
		}
	}
	/**
	 * 二重锁 懒汉式 线程安全
	 * @author zc
	 *
	 */
	public static class Singleton07{
		private volatile static  Singleton07 instance = null;
		
		private Singleton07() {}
		
		public static Singleton07 getInstance() {
			if(instance == null) {
				synchronized(Singleton07.class) {
					if(instance == null) {
						instance = new Singleton07();
					}
				}
			}
			return instance;
		}
	}
	
	public static void main(String[] args) {
		//饿汉式
		System.out.println( Singleton01.getInstance() == Singleton01.getInstance());
		System.out.println( Singleton02.getInstance() == Singleton02.getInstance());
		System.out.println( (Singleton03.INSTANCE == Singleton03.INSTANCE));
		//懒汉式
		System.out.println( Singleton04.getInstance() == Singleton04.getInstance());
		System.out.println( Singleton05.getInstance() == Singleton05.getInstance());
		System.out.println( Singleton06.getInstance() == Singleton06.getInstance());
		System.out.println( Singleton07.getInstance() == Singleton07.getInstance());
		
	}
	
}

 

Publicado 14 artículos originales · ganado elogios 1 · vistas 5526

Supongo que te gusta

Origin blog.csdn.net/Vpn_zc/article/details/84100878
Recomendado
Clasificación