在由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。

出自 新书《Java程序猿面试笔试宝典》官网

最新文章

  1. 【XLL 文档翻译】【第2部分】C API 回调函数 Excel4, Excel12
  2. Android Studio下载与安装
  3. Qt之qSetMessagePattern
  4. ZOJ 2971 Give Me the Number;ZOJ 2311 Inglish-Number Translator (字符处理,防空行,strstr)
  5. POI2001 Gold mine(二叉排序树 黑书经典)
  6. POJ 3080 Blue Jeans (KMP)
  7. 【百度地图API】——国内首款团购网站的地图插件
  8. 你需要知道的这几种 asp.net core 修改默认端口的方式
  9. Linux keepalived+nginx实现主从模式
  10. C语言复习4_while循环
  11. Laravel写讯搜的ini配置文件的一处陷阱
  12. 数据库连接池(基于MySQL数据库)
  13. printf scanf cin cout的区别与特征
  14. 「BZOJ2153」设计铁路 - 斜率DP
  15. ERROR - abandon connection, open stackTrace
  16. Linux 操作日志
  17. STL容器读书笔记
  18. postgresql 表空间创建、删除
  19. EL 和 JSTL
  20. cocos2d::CCFileUtils::sharedFileUtils()->getFileData(szFile, "r", &bufferSize) 不同平台返回值不一样

热门文章

  1. 【马克-to-win】—— 学习笔记
  2. 《R语言实战》读书笔记--第三章 图形初阶(二)
  3. 洛谷P1160 队列安排
  4. checkbox选中 解决兼容问题
  5. API函数的学习与运用
  6. matlab 命令行快捷键
  7. CDH-5.7.0:基于Parcels方式离线安装配置
  8. apache和tomcat群集
  9. [POJ 1935] Journey
  10. Map泛型集合-输入名字输出成绩