• volatile的作用和原理


    1、保持内存可见性
    内存可见性:所有线程都能看到共享内存的最新状态。每次读取前必须先从主内存刷新最新的值。每次写入后必须立即同步回主内存当中。
    Java通过几种原子操作完成工作内存和主内存的交互:
    lock:作用于主内存,把变量标识为线程独占状态。
    unlock:作用于主内存,解除独占状态。
    read:作用主内存,把一个变量的值从主内存传输到线程的工作内存。
    load:作用于工作内存,把read操作传过来的变量值放入工作内存的变量副本中。
    use:作用工作内存,把工作内存当中的一个变量值传给执行引擎。
    assign:作用工作内存,把一个从执行引擎接收到的值赋值给工作内存的变量。
    store:作用于工作内存的变量,把工作内存的一个变量的值传送到主内存中。
    write:作用于主内存的变量,把store操作传来的变量的值放入主内存的变量中。
    volatile如何保持内存可见性
    volatile的特殊规则就是:
    read、load、use动作必须连续出现。
    assign、store、write动作必须连续出现。
    所以,使用volatile变量能够保证:
    每次读取前必须先从主内存刷新最新的值。每次写入后必须立即同步回主内存当中。也就是说,volatile关键字修饰的变量看到的随时是自己的最新值。

    2、防止指令重排
    volatile关键字提供内存屏障的方式来防止指令被重排,编译器在生成字节码文件时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。
    基于保守策略的JMM内存屏障插入策略:
    在每个volatile写操作的前面插入一个StoreStore屏障。
    在每个volatile写操作的后面插入一个StoreLoad屏障。
    在每个volatile读操作的后面插入一个LoadLoad屏障。
    在每个volatile读操作的后面插入一个LoadStore屏障。

    对volatile变量的单次读/写操作可以保证原子性的,如long和double类型变量,但是并不能保证i++这种操作的原子性,因为本质上i++是读、写两次操作。

    volatile不能完全取代Synchronized的位置,只有在一些特殊的场景下,才能适用volatile。总的来说,必须同时满足下面两个条件才能保证在并发环境的线程安全:
    (1)对变量的写操作不依赖于当前值。
    (2)该变量没有包含在具有其他变量的不变式中。

  • 相关阅读:
    HDU
    QDUoj GZS的三角形 棋盘里的数学 思维+杨辉三角
    HDU
    HDU
    CodeForces
    POJ
    QDUOJ 东北大炸弹 宝岛地图-枚举+数组记录+前缀和
    HDU
    QDUOJ 分辣条-01背包恰好装满情况
    HDU
  • 原文地址:https://www.cnblogs.com/xidian2014/p/10322314.html
Copyright © 2020-2023  润新知