In-depth understanding of the Java Memory Model JMM and the volatile keyword

In-depth understanding of the Java Memory Model JMM and the volatile keyword

Concurrent multi-core cache architecture

Java Memory Model

Java threading CPU cache memory model with a similar model, CPU cache model is based on established, Java threads are standardized memory model, masked underlying differences on different computers.

example

Write code to analyze

public class VolatileVisibilityTest {
    private static boolean initFlag = false;

    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("等待数据准备..");
                while (!initFlag){

                }
                System.out.println("============数据准备完毕,执行程序逻辑");
            }
        }).start();
        Thread.sleep(2000);
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                prepareData();
            }
        }).start();
    }

    public static void prepareData(){
 ![](https://img2018.cnblogs.com/blog/1330447/201907/1330447-20190710190530342-1378616179.png)

       System.out.println("数据准备中..");
        initFlag = true;
        System.out.println("数据准备完毕!");
    }
}

The program, printing results

Does not appear

============数据准备完毕,执行程序逻辑

This results

analysis

The first thread to the initFlag is false, the second execution of prepareData () so initFlag is true, but the first thread flag is still false.

If you give initFlag add volatilekeywords:

public class VolatileVisibilityTest {
    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("等待数据准备..");
                while (!initFlag){

                }
                System.out.println("============数据准备完毕,执行程序逻辑");
            }
        }).start();
        Thread.sleep(2000);

        new Thread(new Runnable() {
            @Override
            public void run() {
                prepareData();
            }
        }).start();
    }
    public static void prepareData(){
        System.out.println("数据准备中..");
        initFlag = true;
        System.out.println("数据准备完毕!");
    }
}

Execution of the program, returning a result

JMM atomic operation data

  • read (Read): Read data from main memory
  • load (loading): The main memory to read data written to the working memory
  • use (use): to calculate the data read from the working memory
  • assign (assignment): The computed values ​​reassigned to the working memory
  • strore (storage): the working memory data is written to main memory
  • write (write): will store the last variable value is assigned to the main variables in memory
  • lock (lock): The main memory variable shackles, expressed as a thread exclusive state
  • unlock (unlock): The main memory variable unlock, unlock other thread can lock that variable

The whole process is as follows

JMM cache inconsistencies

  • Bus yoke (low performance)

    • CPU reads data from main memory to cache, this data will be locked in the bus, so that other CPU can not read or write the data until the CPU using the full data release of the lock after the other CPU can read that data.

  • MESI cache coherency protocol

    • Multiple CPU reads the same data from main memory to each cache, when a certain CPU cache modify the data, the data is immediately synchronized back to the main memory, CPU through the other 总线嗅探机制can perceive changes in their data so cache data failed.

Volatile visibility principle underlying implementation

  • Volatile cache to achieve visibility principle

    • 底层实现主要是通过汇编lock前缀指令,它会锁定这块内存区域的缓存并回写到主内存,此操作被称为“缓存锁定”,MESI缓存一致性协议机制会阻止同时修改被两个以上处理器缓存的内存区域数据。一个处理器的缓存值通过总线回写到内存会导致其他处理器响应的缓存失效。

    Java程序汇编代码查看

    • -server -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,*VolatileVisibilityTest.prepareData
    • 需要先下载hsdis-amd64

IDEA这样设置

显式出的结果,其中volatile修饰的汇编代码如下:

0x000000000349eaff: lock add dword ptr [rsp],0h ;*putstatic initFlag
; - com.tugohost.concurrent.VolatileVisibilityTest::prepareData@9 (line 31)

可见性、原子性与有序性

  • 并发编程三大特性:可见性,原子性,有序性
  • Volatile保证可见性与有序性,但是不保证原子性,保证原子性需要借助synchronized这样的锁机制。

Guess you like

Origin www.cnblogs.com/Tu9oh0st/p/11165905.html