zoukankan      html  css  js  c++  java
  • Java volatile keyword

    前言:

    用在多线程,同步变量。线程为了提高效率,将某个成员(A)变量拷贝了一份(B)。线程中对A的訪问事实上訪问的是B。仅仅在某些动作时才进行A和B的同步。因此存在A和B不

    一致的情况。volatile就是用来避免这个中情况的。volatile告诉jvm,它所修饰的变量不保留拷贝,直接訪问主内存中的A。

    在Java内存模型中,有main memory,每一个线程也

    有自己的memory(寄存器).为了性能,一个线程会在自己的memory中保持要訪问的变量的副本。

    这样就会出现同一个变量在某个瞬时,在一个线程的memory中的值可能与另

    一个线程memory中的值,或者main memory中的值不一致的情况。

    一个变量声明为volatile,就意味着这个变量是随时会被其它线程改动的。因此不能将它cache在线程memory中。

    1.特性:

    volatilekeyword确保了应用中的可视性。假设你将一个域声明为volatile,那么仅仅要这个域产生了写操作,那么全部的读操作都能够看到这个改动。

    2. 原子性:

    volatile修饰的变量不同意线程内部缓存和重排序。即直接改动内存。所以对其它线程是可见的。但volatile仅仅能让被它修饰的内容具有可见性,但不能保证它具有原子性。

    仅仅会影响可见性,不会影响原子性。

    3.其它:

    1) 保证了不同线程对这个变量进行操作时的可见性,即一个线程改动了某个变量的值,这新值对其它线程来说是马上可见的。

      2) 禁止进行指令重排序。

    4.实现机制:

    观察增加volatilekeyword和没有增加volatilekeyword时所生成的汇编代码发现,增加volatilekeyword时,会多出一个lock前缀指令。lock前缀指令实际上相当于一个内存屏障(也

    称内存栅栏)。内存屏障会提供三个功能:

    1) 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在运行到内存屏障这句指令时。在它前面的操作已全

    部完毕。

    2) 它会强制将对缓存的改动操作马上写入主存。

    3) 假设是写操作。它会导致其它CPU中相应的缓存行无效。

    5.通常volatile必须具备下面两个条件:

    1) 对变量的写操作不依赖于当前值。

    2) 该变量没有包括在具有其它变量的不变式中。

  • 相关阅读:
    linux查看CPU和内存信息
    linux yum命令详解
    查看文件中关键字前后几行的内容
    vue.js+web storm安装及第一个vue.js
    android GPS: code should explicitly check to see if permission is available
    ASP.NET MVC Identity 使用自己的SQL Server数据库
    阿里云服务器,tomcat启动,一直卡在At least one JAR was scanned for TLDs yet contained no TLDs就不动了
    ASP.NET MVC4 MVC 当前上下文中不存在名称“Scripts”
    python 将windows字体中的汉字生成图片的方法
    Java android DES+Base64加密解密
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7099214.html
Copyright © 2011-2022 走看看