Java虚拟机学习之Java内存模型

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012342524/article/details/76152626

我们都站在巨人的肩膀上


  1. 概述

    • 内存模型:可以理解为在特定的操作协议下,对特定的内存或者或者缓存进行读写访问的过程抽象
    • 这类协议有:MSI/MESI/MOSI/Synapse/Firefly以及Dragon/Protocol等

    • Java内存模型图

  2. Java内存模型

    Java虚拟机规范中试图定义一种Java内存模型来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java在各种平台下都能达到一致的内存访问效果。

    1. 主内存和工作内存

      • Java内存模型定义的目标是 定义程序中各个变量的访问规则

      • 此处的变量与Java编程中的变量有所区别,主要是非局部变量和方法参数,因为此二者属于线程私有,不会存在竞争关系,有竞争关系的变量 如:实例变量、静态字段和构成数组对象的元素。

      • Java内存模型规定了所有变量都存储在主内存

      • 每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用到的主内存副本拷贝,线程对变量所有的操作都必须在工作内存中进行,不能在主内存中进行。

      • 线程、主内存和工作内存关系

    2. 内存间交互操作

      • Java内存模型中定义了8中操作来完成,虚拟机保证下面每一种操作都是原子性的不可再分的(double和long有特殊规则)

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

      • Java内存模型还规定了在执行上述8种疾病操作时必须满足如下规则

        1. 不允许read和load、store和write操作之一单独出现
        2. 不允许一个线程丢弃它的最近的assign
        3. 不允许一个线程无原因地(没有发生任何assign操作)把数据从线程的工作内存同步回主内存
        4. 一个新的变量只能在主内存中“诞生”,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量
        5. 一个变量在同一个时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程执行多次,多次lock后,只有相同次数的unlock操作,才能解锁该变量
        6. 如果对一个变量执行lock操作,那将会清空工作内存中次变量的值,在执行引擎使用这个变量,需要重新执行load或assign操作初始化变量的值
        7. 如果一个变量没有被lock,那也不能执行unlock,也不允许unlock其他线程锁定的变量
        8. 对一个变量执行unlock操作之前,必须先把次变量同步回主内存(执行store、write操作)
    3. 对于volatile型变量的特殊规则(待更新)

    4. 对于long和double型变量的特殊规则(待更新)
    5. 原子性、可见性、有序性(待更新)
    6. 先行发生原则 (待更新)
展开阅读全文

没有更多推荐了,返回首页