• JVM内存模型


    JVM内存模型(JAVA Memory Model,简称 JMM)

    JMM:用于定义变量(所有线程的共享变量,不能是局部变量)的访问规则。

    JMM将内存划分为两个区:主内存区和工作内存区

    • 主内存区:真实存放变量
    • 工作内存:主内存中变量的副本,供各个线程使用

    注意

    • 各个线程 只能访问自己私有的工作内存(不能访问其他线程的内存,也不能访问主内存)
    • 不同线程之间可以通过主内存间接的访问其他线程的工作内存。

    各个线程只能访问自己的工作内存,那么A线程如何获取B线程的值?

    1. 将线程B的数据同步到主内存(Save:将工作内存的数据刷到主内存)
    2. 线程A获取主内存中的最新数据(Load:主内存到工作内存)

    不同线程之间数据如何交互

    刚才介绍了 Save 和 Load 两个动作,但是不同线程之间数据交互的步骤不仅仅只有这两个,下面我们完整介绍一下交互步骤。

    1. Lock : 将主内存中的数据,标识为一条线程的独占状态。
    2. Read : 将主内存中的变量,读取到工作内存中。
    3. Load:将上一步读取的变量,拷贝到变量副本当中。
    4. Use:将工作内存中的变量副本,传递给线程去使用。
    5. Assign:将线程正在使用的变量,传递给工作内存中的变量副本。
    6. Store:将工作内存中变量副本的值,传递到主内存中。
    7. Write:将变量副本作为主内存中的变量进行储存。
    8. UnLock:解除线程的独占状态。

    JVM要求以上的八个动作必须是原子性的。

    但是JVM对于64位的数据类型(long/double)有非原子性协议!!long和double占用的字节数都是8,也就是64bits。在32位操作系统上对64位的数据的读写要分两步完成,每一步取32位数据。这样对double和long的赋值操作就会有问题:如果有两个线程同时写一个变量内存,一个进程写低32位,而另一个写高32位,这样将导致获取的64位数据是失效的数据。因此需要使用volatile关键字来防止此类现象。volatile本身不保证获取和设置操作的原子性,仅仅保持修改的可见性。但是java的内存模型保证声明为volatile的long和double变量的get和set操作是原子的。

  • 相关阅读:
    AUDIT审计的一些使用
    HOW TO PERFORM BLOCK MEDIA RECOVERY (BMR) WHEN BACKUPS ARE NOT TAKEN BY RMAN. (Doc ID 342972.1)
    使用BBED理解和修改Oracle数据块
    Using Class of Secure Transport (COST) to Restrict Instance Registration in Oracle RAC [ID 1340831.1]
    调试利器GDB概念
    第4章 思科IOS
    第3章 ip地址和子网划分
    第2章 TCPIP
    2020年阅读过的黑客资源推荐篇
    第1章 计算机网络
  • 原文地址:https://www.cnblogs.com/leizzige/p/14165305.html
Copyright © 2020-2023  润新知