Publicación Segura (safe publication) es la garantía de distribución segura de un objeto entre hilos: si un hilo crea e inicializa un objeto, otro hilo siempre verá el objeto completamente construido, y no su estado parcialmente inicializado.
Sin publicación segura, se puede obtener una condición de carrera: un hilo ve una parte no inicializada del objeto, incluso si el constructor ya ha terminado.
Formas de garantizar la publicación segura:
Ejemplo (no seguro):
public class Holder { private int n; public Holder(int n) { this.n = n; } } Holder holder; void publish() { holder = new Holder(42); } // Seguridad no garantizada
¡Pueden verse objetos no completamente construidos!
Ejemplo (seguro):
volatile Holder holder; void publish() { holder = new Holder(42); } // La lectura de holder también será segura
Si en el objeto todos los campos son final, ¿garantiza esto siempre la publicación segura?
Respuesta: No, solo si la referencia al nuevo objeto se publica antes de terminar el constructor. Si la referencia se comparte con otros hilos antes de que finalice el constructor, los campos pueden no estar completamente inicializados. Se debe evitar la publicación de this o referencias a objetos no completamente construidos durante la ejecución del constructor.
Ejemplo (¡peligroso!):
public class PublishEscape { public static PublishEscape instance; public PublishEscape() { instance = this; // ¡Mal! this se publica antes de terminar el constructor } }
Historia
Un desarrollador asignó una referencia a una instancia de Service a un campo accesible a través de static, antes de que el constructor terminara. Como resultado, otro hilo recibió un objeto parcialmente construido, lo que causó un comportamiento impredecible en producción.
Historia
En una aplicación web, los objetos singleton se creaban sin sincronización adicional. Bajo carga, algunos hilos obtenían null o campos incorrectamente inicializados, lo que conducía a Intermittent NullPointerException.
Historia
En una biblioteca, se utilizó una List común para el caché entre hilos; faltaba publicación segura y la inicialización no garantizaba visibilidad a nuevos hilos. Como resultado, el caché funcionaba de manera caótica, comprometiendo la integridad de los datos.