Modelo de memoria Java:
Operación atómica de datos JMM:
Pasos específicos:
Subproceso 1: Primero lea la variable initFlag read, luego cargue en la memoria de trabajo, use usa el hilo 1 para ejecutar el código! InitFlag
Subproceso 2: primero lea la variable initFlag read, luego cargue en la memoria de trabajo, use el hilo 2 para ejecutar el código initFlag = true, luego asigne reasignación, almacene las tiendas y escriba en la memoria principal, escriba las escrituras en la memoria principal variable. (El hilo 2 bloquea el bloqueo de la línea de caché y desbloquea el desbloqueo después de escribir escrituras en la memoria principal para evitar que initFlag sea leído como falso por el hilo 1 antes de escribir en la memoria principal).
Subproceso 1: Debido a que initFlag es modificado por volátil, se usa el protocolo de coherencia de caché MESI, el mecanismo de rastreo de bus de la CPU del subproceso 1 monitorea la modificación del valor initFlag, initFlag = false se convierte en verdadero en el subproceso 1 y sale del bucle para continuar la ejecución, lo que refleja la operación sincrónica de múltiples subprocesos Visibilidad de una copia de la variable compartida . Si initFlag no es modificado por volatile, el hilo 1 no percibirá el cambio en initFlag y el bucle no se detendrá.
El código de la imagen:
public class VolatileVisibilityTest {
//volatile变量,用来确保将变量的更新操作通知到其他线程。
private static volatile boolean initFlag = false;
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("waiting data...");
while (!initFlag) {
}
System.out.println("==============success");
}
}).start();
Thread.sleep(2000);
new Thread(new Runnable() {
@Override
public void run() {
prepareData();
}
}).start();
}
public static void prepareData(){
System.out.println("preparing data...");
initFlag = true;
System.out.println("prepare data end...");
}
}
Resuelva el problema de la inconsistencia de la caché jmm:
Bloqueo de bus: el
bloqueo y desbloqueo bloquearán la memoria principal, el bloqueo de bus generalmente no se usa, la eficiencia es demasiado baja y similar a un solo hilo. Generalmente use el protocolo de coherencia de caché MESI.