Volatile cache visibility implementation principle (the specific steps of JMM data atomic operation)

Java memory model:

Insert picture description here

JMM data atomic operation:

Insert picture description here

Specific steps:

Insert picture description here

Thread 1: First read the initFlag variable read, then load into the working memory, use uses thread 1 to execute the code! initFlag

Thread 2: first read the initFlag variable read, then load into the working memory, use uses thread 2 to execute the code initFlag=true, then assign re-assignment, store stores and writes to the main memory, write writes to the main memory variable. (Thread 2 locks the cache line lock, and unlocks unlock after write writes to the main memory to prevent initFlag from being read as false by thread 1 before writing to the main memory.)

Thread 1: Because initFlag is modified by volatile, MESI cache coherency protocol is used, thread 1 cpu bus sniffing mechanism monitors the modification of initFlag value, initFlag=false becomes true in thread 1 and exits the loop to continue execution, which reflects the synchronous operation of multiple threads Visibility of a copy of the shared variable . If the initFlag is not modified by volatile, thread 1 will not perceive the change in initFlag, and the loop will not stop.

The code in the picture:

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...");
        }
}

Solve the problem of inconsistent jmm cache:

Insert picture description here

Insert picture description here

Insert picture description here


Bus lock:
lock and unlock will lock the main memory, bus lock is generally not used, the efficiency is too low, and similar to single thread. Generally use the MESI cache coherency protocol.
Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_41699562/article/details/104150671