zoukankan      html  css  js  c++  java
  • 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)该变量没有包含在具有其他变量的不变式中。

  • 相关阅读:
    hbuilder外置服务器设置(局域网移动端调试)
    【转载】解决微信OAuth2.0网页授权回调域名只能设置一个的问题
    【转载】如何使用PHP构建一个高性能的弹幕后端服务
    【转载】PHP学习资源整理
    【php基础】php运算符 php取整函数
    Browser 对象(一、history)
    Opencv 图像平滑基础二维离散卷积C++ API
    Opencv 图像平滑基础二维离散卷积 python API
    道格拉斯轨迹抽稀算法Android 百度地图SDK
    Opencv 几何变换
  • 原文地址:https://www.cnblogs.com/xidian2014/p/10322314.html
Copyright © 2011-2022 走看看