zoukankan      html  css  js  c++  java
  • Java volatile 有什么作用

     

    在由Java语言编写的程序中。有时候为了提高程序的执行效率,编译器会自己主动对其进行优化,把经常被訪问的变量缓存起来,程序在读取这个变量的时候有可能会直接从缓存(比如寄存器)中来读取这个值。而不会去内存中读取。这样做的一个优点是提高了程序的执行效率,但当遇到多线程编程时。变量的值可能由于别的线程而改变了,而该缓存的值不会相应改变,从而造成应用程序读取的值和实际的变量值不一致。比如,在本次线程内,当读取一个变量时,为提高存取速度,会先把变量读取到一个缓存中,当以后再取变量值时,就直接从缓存中取值。当变量值在本线程里改变时,会同一时候把变量的新值复制到该缓存中,以便保持一致。

           volatile是一个类型修饰符(typespecifier)。它是被设计用来修饰被不同线程訪问和改动的变量。被volatile类型定义的变量,系统每次用到它的时候都是直接从相应的内存其中提取,而不会利用缓存。在使用了volatile修饰成员变量后,全部线程在不论什么时候看到的变量的值都是最新的。以下给出一个使用volatile的演示样例。

    public class MyThread  implements  Runnable {

           private volatile Boolean flag;

           public void stop() {

                  flag = false;

           }

           public void run() {

                  while(flag)

                         ;//do something

           }

    }

           以上代码演示样例是用来停止线程最经常使用的一种方法。假设boolean类型的变量flag没有被声明为volatile,那么,当这个线程的run方法在推断flag值的时候,使用的有可能是缓存中的值,此时就不能及时地获取其他线程对flag所做的操作,因此会导致线程不能及时地停止。

           须要注意的是,由于volatile不能保证操作的原子性,因此,普通情况下volatile不能取代sychronized。此外,使用volatile会阻止编译器对代码的优化,因此会减少程序的执行效率。所以,除非迫不得已。否则。能不使用volatile。则尽量不要使用volatile。

    当多个线程进行操作共享数据时,可以保证内存中的数据可见。底层原理:内存栅栏。使用volatile关键字修饰时,可理解为对数据的操作都在主存中进行。

    private volatile boolean flag = false;

    相较于synchronized是一种较为轻量级的同步策略。

    注意:

    • volatile不具备“互斥性”
    • volatile不能保证变量的“原子性”
  • 相关阅读:
    QT多重继承的时候,要把QObject放在最前面,否则报错——C++认为人性本恶,默认都是私有的,这点和Delphi的世界观不一样
    动态库的搜索路径
    载入OpenSSL的动态库——学会使用tryToLoadOpenSslWin32Library和QPair
    Physical Standby Database Failover
    ARM和X86功耗差别的深层原因探讨
    Qt 鼠标样式特效探索样例(一)——利用时间器调用QWidget.move()函数
    QT---线程间通信
    Qt :非window子窗体的透明度设置
    QT:给Widget设置背景图片——设置Widget的调色板,调色板使用图片和背景色
    用友CDM系统,将货位间商品移库单(一步)修改为内调出入库单(一步)方法使用
  • 原文地址:https://www.cnblogs.com/zhaoyanhaoBlog/p/9664561.html
Copyright © 2011-2022 走看看