El volatile
impide que las escrituras en memoria de ser reordenado, haciendo imposible que otros hilos lean campos no inicializados de su singleton a través del puntero de singleton.
Tenga en cuenta esta situación: el hilo A descubre que uniqueInstance == null
, bloquea, confirma que todavía está null
, y llama al constructor de singleton. El constructor realiza una escritura en el miembro XYZ
dentro de Singleton y lo devuelve. El subproceso A ahora escribe la referencia al singleton recién creado en uniqueInstance
, y se prepara para liberar su bloqueo.
Al igual que el hilo A se prepara para soltar su bloqueo, aparece el hilo B y descubre que uniqueInstance
no es uniqueInstance
, no es . El subproceso B
tiene acceso a uniqueInstance.XYZ
pensando que se ha inicializado, pero como la CPU ha reordenado las escrituras, los datos que el subproceso A ha escrito en XYZ
no se han hecho visibles al subproceso B. Por lo tanto, el subproceso B ve un valor incorrecto dentro de XYZ
, que es incorrecto.
Cuando se marca uniqueInstance
volátil, una barrera de memoria se inserta. Todas las escrituras iniciadas antes de uniqueInstance
se completarán antes de que se modifique el uniqueInstance
, evitando la situación de reordenamiento descrita anteriormente.
Puestos relacionados con [aquí] (https : //stackoverflow.com/q/18093735/465053) y [aquí] (https://stackoverflow.com/q/12316406/465053) acerca de por qué doble control es aún necesario en primer lugar. – RBT