volatile在JVM内存交互中的操作

6 篇文章 0 订阅

volatile在JVM内存交互中的操作

只是做一个简单的记录 ^_^

JMM

  • 主内存(共享): 本地方法区 + 堆
  • 工作内存(线程私有): 栈 + 寄存器(程序计数器 + CPU高速缓存区)
  • 几个规则:
    • 所有变量都会存在主内存中,工作内存会保存其中部分变量的拷贝
    • 线程对变量的操作必须在工作内存中进行,不能直接读写主内存的变量
    • 不同线程的工作内存是私有的,不能相互直接访问,必须通过主内存传递
  • 示意图
    JMM模型示意图

JVM内存屏障(JVM规范)

  • JVM内存屏障(保证有序)
    • StoreStore
    • StoreLoad
    • LoadLoad
    • LoadStore
  • volatile在JVM层的抽象
    StoreStoreBarrier
    volatile变量的写操作
    StoreLoadBarrier
    
    LoadLoadBarrier
    volatile变量的读操作
    LoadStoreBarrier
    
  • volatile变量的写操作happens-before于这个volatile变量的读操作

JVM内存交互操作(Hotspot)

  • JVM定义了8种操作(原子)来完成主内存与工作内存之间的交互
    • read: 读取,将变量从主内存传到工作内存,接着将执行load
    • load: 载入,将read操作拿到的变量放到工作内存的变量
    • use: 使用,将工作内存的变量传给执行引擎
    • assign: 赋值,将执行引擎得到的值赋值给工作内存的变量
    • store: 存储,将工作的内存变量的值传到主内存中,接着将执行write
    • write: 写入,将store操作拿到变量放到主内存的变量
    • lock: 锁定,将主内存变量标识为线程独占状态
    • unlock: 解锁,将主内存变量解除线程独占状态,其后可以被其他线程锁定

volatile在硬件层的操作(Hotspot+Windows)

  • volatile会触发lock/unlock,在硬件层的操作流程大致如下
    1. lock -> 锁住主内存变量a,当前线程独占
    2. 变量a -> store进入主内存 -> wirte给主内存的变量a
    3. unlock -> 解除独占状态
    4. lock操作会触发MESI(IntelCPU)缓存一致性协议:CPU总线嗅探机制被触发 -> 其他线程的该变量a失效 -> 其他线程重新从主内存获取变量a

示例-非volatile修饰的变量赋值操作

  • 代码示例
    private static int a = 10;
    
    public static void main(String[] args) {
        new Thread(() -> {
            a = 15;
        }).start();
    }
    
  • 示意图
    -------主内存---------|-------工作内存---------|---------CPU--------
    a=10            --read-->--load-->  a=10   
                                                --use-->    计算
                                        a=15    <--assign--    
    a=15     <--write--<--store-- 
    

示例-volatile修饰的变量赋值操作(lock/unlock)

  • 代码示例
    private static volatile int a = 10;
    
    public static void main(String[] args) {
        new Thread(() -> {
            a = 15;
        }).start();
    }
    
  • 示意图
    -------主内存---------|-------工作内存---------|---------CPU--------
    a=10            --read-->--load-->  a=10   
                                                --use-->    计算
                                        a=15    <--assign--   
    -------------lock------------       
    a=15     <--write--<--store--       
    ------------unlock-----------
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值