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) 该变量没有包括在具有其它变量的不变式中。

  • 相关阅读:
    ASP.NET 读取FTP文件流
    ASP.NET XML序列化
    ASP.NET Core 微信支付(四)【支付结果通知回调(未按照官方步骤) APIV3】
    ASP.NET Core 微信支付(三)【查询订单 APIV3】
    pytest系列(四)
    pytest系列(五)
    2021金三银四
    2021金三银四
    requests- 处理 multipartform-data 类型的上传接口
    html5 video(html中播放视频的标签)
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7099214.html
Copyright © 2011-2022 走看看