Repaso
English

¿Cuál es la forma más segura de escribir un Singleton thread-safe en Java?

Opciones

  1. Un campo public static inicializado de forma lazy y sin sincronización
  2. Un enum de un solo elemento, o una holder class con una instancia static final (Opción correcta)
  3. Una clase normal con un constructor público que cualquiera puede llamar
  4. Una clase con todos sus campos marcados con volatile

Respuesta

Un enum de un solo elemento, o una holder class / instancia static final creada al arrancar

Por qué

Singleton significa una instancia para toda la aplicación. La inicialización lazy con if (instance == null) instance = new X(); NO es thread-safe: dos threads podrían crear dos instancias.

Opciones seguras:

  • enum Config { INSTANCE; ... }: la JVM garantiza una instancia y además resiste la serialización y los ataques por reflection (lo recomienda Effective Java).
  • Instancia inmediata private static final X INSTANCE = new X();.
  • Initialization-on-demand holder (una clase interna private static que guarda la instancia).
  • El double-checked locking solo funciona si el campo es volatile.

En apps Spring, normalmente deja que el contenedor gestione los beans singleton.

public enum AppConfig {
    INSTANCE;
    public String env() { return "prod"; }
}
// AppConfig.INSTANCE.env()

Recuerda

Singleton en Java: prefiere enum o deja que lo gestione Spring.

Términos clave

Practica esta pregunta en Repaso