2009-09-30 23 views

Respuesta

6

Quizás la mejor manera es usar una enumeración con una sola instancia. Esto tiene el beneficio adicional de ser serializable y garantizar el singleton-ness contra la serialización y la reflexión, lo que ninguna implementación de Singleton "directa" hace (¿privado? ¡Tengo reflexión, me burlo burlonamente de tus modificadores de acceso!). También es muy simple de implementar:

public enum Singleton { 
    INSTANCE; 

    // fields and methods go here 
} 
+0

+1 por burlarse de los modificadores de acceso. Yo lol'd. :) – corsiKa

0

Los Singletons no son seguros para roscar por defecto. La forma común de crear un singleton es tener un método de fábrica que maneje la creación de la instancia única. De esa forma puedes controlar la creación de instancias.

2
public class Singleton { 
    public static final Singleton INSTANCE = new Singleton(); 
    private Singleton() { ... } 
} 

El uso de una variable de instancia estática es preferible a la clase interna "Titular". Si lo desea, también puede hacer que el miembro estático sea privado y proporcionar un método para acceder a él, pero todo lo que hace es agregar otra llamada a método a la pila.

+0

Más bien depende de lo que intenta lograr en cuanto a lo que se prefiere - el titular le da un singleton perezosa, la versión más simple no le da carga lenta. –

+0

Sí, lo hace. Java no carga clases hasta que se usan por primera vez. –

+1

No del todo cierto. Los carga cuando se mencionan por primera vez, p. en el método firma de otra clase. – skaffman

1

What about lazy instanciation: getInstance() devuelve el singleton o lo crea si es la primera llamada.

public class MySingleton 
{ 
    private static MySingleton instance; 

    private MySingleton() 
    { 
     // construct object . . . 
    } 

    // For lazy initialization 
    public static synchronized MySingleton getInstance() 
    { 
     if (instance==null) 
     { 
      instance = new MySingleton(); 
     } 
     return instance; 
    } 

    // Remainder of class definition . . . 
} 
+1

La instanciación lenta casi nunca es necesaria, y si lo es, Java carga las clases perezosamente, por lo que crear la instancia en la declaración * es * instanciación lenta - sin sobrecarga de sincronización (en casos muy raros no es lo suficientemente floja y la respuesta de skaffman es mejor) . –

+0

También tenga en cuenta que esta implementación sincroniza todos los intentos para obtener una referencia a la instancia. Como la mayoría de los códigos harán algo como: Singleton.getInstance.doSomething(); Singleton.getInstance.doSomethingElse(); El efecto general sería una sincronización adicional que limitaría severamente la concurrencia sin garantías de seguridad de subprocesos en términos de acceso/mutación de miembro. –

+0

El bloqueo con doble comprobación en java está roto http://www.javaworld.com/jw-02-2001/jw-0209-double.html En resumen, esta forma de garantizar que esta clase se instancia solo una vez puede dar como resultado problemas de concurrencia difíciles de encontrar. Nunca use esto – Buhb

11

¿La mejor manera de hacer un singleton? Usa una enumeración

public enum Singleton { 
    INSTANCE; 
    public void foo(){ ... } 
} 

// Usage: 
Singleton.INSTANCE.foo(); 

Tienes un montón de ayuda de la máquina virtual no sólo para evitar la doble ejemplificación, sino que también ayuda a evitar la corrupción deserialización.

0

Si le importa la simultaneidad, no utilizará el estado global compartido.

+2

Si el singleton contiene la acumulación de resultados de un singular problema paralelizado, ¿por qué no? Un singleton personifica el estado global y, como tal, sería un escenario de uso justo. –

+1

Existen varios casos de uso para clases representadas con solo una instancia compartida entre procesos.Una aplicación web típica y bien diseñada que utilice un resorte probablemente tendrá un grupo de clases instanciadas en un alcance único, compartido entre los hilos del trabajador. – Buhb

Cuestiones relacionadas