Red de conocimientos turísticos - Conocimientos sobre calendario chino - ¿Java en modo Singleton usa un modificador de sincronización para doble bloqueo y luego usa volátil?

¿Java en modo Singleton usa un modificador de sincronización para doble bloqueo y luego usa volátil?

instancia única sin modificador volátil

[java]Ver copia ordinaria

Clase pública Singleton {

Singleton estático privado instancia única;

Singleton privado ( ){

}

getInstance Singleton estático público(){

if(uniqueInstance == null){ //#1

sincronizado( Singleton.class){ //#2

if(uniqueInstance == null){ //#3

uniqueInstance = new Singleton(); //#4

p>

System.out.println(Thread .currentThread().getName() + ": la instancia única se inicializa...") ; //#5.1

} else {

} else {

p>

System.out.println(Thread .currentThread().getName() + ": UniqueInstance no es nulo ahora...") //#; 5.2

}

}

}

devolver instancia única

}

}

}

Esto puede hacer que se creen dos instancias del singleton resultante, lo cual es inconsistente con el singleton.

Razones:

1 El subproceso 2 ingresa al subproceso n.° 1 y la instancia única del subproceso secundario está vacía. El subproceso 2 transfiere los recursos de la CPU al subproceso 3. El subproceso 3 ingresa al subproceso n.° 1, en este momento la instancia única del subproceso secundario. El hilo está vacío y el hilo 3 transfiere los recursos de CPO al hilo 2

3. El hilo 2 ejecuta #2, #3, #4, #5.1 y finalmente crea una instancia única en el hilo 2. Una vez que el subproceso 2 completa la ejecución, el CPO se entrega al subproceso 3

4. El subproceso 3 continúa ejecutándose en el n.° 1 y, cuando llega al n.° 3, la instancia única está vacía ya que estaba en el n.° 1. Cuando se ejecuta en el n.° 3, el subproceso 3 todavía está ejecutando el n.° 4, n.° 5.1 porque la instancia única que obtuvo del n.° 1 todavía está vacía (no obtuvo la última instancia única del subproceso 2 a tiempo)

5. Finalmente, crea una instancia de UniqueInstance tanto en el subproceso 2 como en el subproceso 3

Ejemplo 2: Instancia única modificada usando volátil

No publicaré código duplicado aquí porque solo agregaré un volátil para modificar el miembro. variable: instancia única,

Creando así un singleton.

Análisis de causa:

volátil (java5): puede garantizar la visibilidad en subprocesos múltiples;

Leer volátil: siempre que una declaración de un subproceso secundario Cuando un volátil Se utiliza una variable, se copiará nuevamente desde el hilo principal, asegurando así que el subproceso sea el mismo que el hilo principal.

Escritura en variables volátiles: siempre que un subproceso secundario quiera escribir en una variable volátil, se sincronizará con el subproceso principal después de la lectura, lo que garantiza que las variables del subproceso principal estén actualizadas.

1. El subproceso 2 ingresa al n.° 1. En este momento, la instancia única del subproceso secundario está vacía (el modelo de memoria Java copiará UniqueInstance = null del subproceso principal al subproceso secundario 2) y El subproceso 2 cede los recursos de la CPU al subproceso 3.

2. El subproceso 3 ingresa al n.° 1. En este momento, la instancia única del subproceso secundario está vacía (el modelo de memoria Java copiará la instancia única = nulo de. el subproceso principal al subproceso secundario (el subproceso 2) y el subproceso 3 transferirá los recursos de CPO al subproceso 2

3. El hilo 2, que a su vez ejecutará los números 2, 3, 4, 5.1, finalmente crea una instancia única en el hilo 2 (dado que es una variable volátil, se sincronizará inmediatamente con la variable del hilo principal). Una vez que el subproceso 2 completa la ejecución, sus recursos de CPO se liberan al subproceso 3

4. El subproceso 3 continuará ejecutándose del n.° 1 al n.° 3 y, al llegar al n.° 3, se ejecutará nuevamente desde el recurso CPO al subproceso 3 y comenzará a ejecutarse desde el recurso CPO nuevamente. Cuando se ejecuta #3, se hace otra copia de UniqueInstance!=null del hilo principal, por lo que el hilo 3 se ejecuta directamente en #5.2

5. Finalmente, Thread 3 ya no crea instancias de UniqueInstance.