JMM


请你谈谈你对Volatile的理解
Volatile:java虚拟机提供的轻量级的同步机制(Synchronized)

  • 保证可见性
  • 不保证原子性
  • 禁止指令重排

什么是JMM(JVM是java虚拟机)

JMM是java中的内存模型,不存在的东西,是一种概念,约定
JMM即为JAVA 内存模型(java memory model),JMM规定了内存主要划分为主内存和工作内存两种。主内存对应的是Java堆中的对象实例部分,工作内存对应的是栈中的部分区域。每条线程拥有各自的工作内存,工作内存中的变量是主内存中的一份拷贝

关于JMM的一些同步的约定

  1. 线程解锁前,必须把共享变量 立刻 先从主存中拷贝一份到自己的工作内存进行操作
  2. 线程加锁前,必须读取主存中的最新值带线程自己的工作内存中
  3. 加锁和解锁是同一把锁

线程 工作内存,主内存

JMM的八种操作

lock (锁定):作用于主内存的变量,把一个变量标识为线程独占状态
unlock (解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
read (读取):作用于主内存变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用
load (载入):作用于工作内存的变量,它把read操作从主存中变量放入工作内存中
use (使用):作用于工作内存中的变量,它把工作内存中的变量传输给执行引擎,每当虚拟机遇到一个需要使用到变量的值,就会使用到这个指令
assign (赋值):作用于工作内存中的变量,它把一个从执行引擎中接受到的值放入工作内存的变量副本中
store (存储):作用于主内存中的变量,它把一个从工作内存中一个变量的值传送到主内存中,以便后续的write使用
write  (写入):作用于主内存中的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中

八种操作的规则

  1. 不允许read和load、store和write操作之一单独出现。即使用了read必须load,使用了store必须write
  2. 不允许线程丢弃他最近的assign操作,即工作变量的数据改变了之后,必须告知主存
  3. 不允许一个线程将没有assign的数据从工作内存同步回主内存
  4. 一个新的变量必须在主内存中诞生,不允许工作内存直接使用一个未被初始化的变量。就是怼变量实施use、store操作之前,必须经过assign和load操作
  5. 一个变量同一时间只有一个线程能对其进行lock。多次lock后,必须执行相同次数的unlock才能解锁
  6. 如果对一个变量进行lock操作,会清空所有工作内存中此变量的值,在执行引擎使用这个变量前,必须重新load或assign操作初始化变量的值
  7. 如果一个变量没有被lock,就不能对其进行unlock操作。也不能unlock一个被其他线程锁住的变量
  8. 对一个变量进行unlock操作之前,必须把此变量同步回主内存
public class JMMDemo {
    private static int num=0;
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while(num==0){

            }
        }).start();
        TimeUnit.SECONDS.sleep(1);
        num=1;  //主内存中的值一旦发生变化如何通知另一个线程,另一个线程不知道主内存的值被修改过了 ==>Volatile
        System.out.println(num);
    }
}