什么是JMM?

JMM(Java Memory Model):Java内存模型。

JMM是一种约定或者概念,是一种不存在的东西,

个人理解

JMM内存模型中规定了所有的变量都存储在主内存中

而每个线程都有一个工作内存,工作内存保存了这个线程所使用到的主内存变量副本拷贝

对变量的所有操作(读取、赋值等)都必须在工作内存进行,不允许直接读取主内存的变量。

不同的线程之间无法直接访问到对方的工作内存,需要同过主内存进行传递。

而当一个线程拷贝的变量被修改后,必须立刻刷新到主内存中。并且要读取主内存最新的值到工作内存中。

以达到 缓存一致性协议。

关于JMM的一些同步的约定:
1、线程解锁前,必须把共享变量立刻刷回主存。
2、线程加锁前,必须读取主存中的最新值到工作内存中!
3、加锁和解锁是同一把锁

主内存工作内存的8种操作

对这些8种操作分析:

但是引发了一个问题:

A线程并不知道flag变量被B线程修改了。引发了可见性问题。

代码演示:

结果】使用没用声明volatile的num,while会一直循环,因为while所在线程它不知道num被改变为1了。

package com.tvolatile;

import java.util.concurrent.TimeUnit;

public class TestVolatile {
    //private static volatile int num = 0;  //保证可见性
    private static volatile int num = 0;  //不保证可见性
    public static void main(String[] args) {
        new Thread(()->{
            while (num == 0){ //无限循环

            }
        }).start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        num = 1;
        System.out.println(num);
    }
}

那怎么保证数据同步问题呢? 可以使用Volatile、final或synchronized,Lock。
可以看我的下一篇:用Volatile保证原子性