Principio de realización de visibilidad de caché volátil (los pasos específicos de la operación atómica de datos de JMM)

Modelo de memoria Java:

Inserte la descripción de la imagen aquí

Operación atómica de datos JMM:

Inserte la descripción de la imagen aquí

Pasos específicos:

Inserte la descripción de la imagen aquí

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:

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí


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.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_41699562/article/details/104150671
Recomendado
Clasificación