http://blog.csdn.net/yizhenn/article/details/52384477

学过计算机组成原理的一定知道,为了解决内存速度跟不上CPU速度这个问题,在CPU的设计中加入了缓存机制,缓存的速度介于CPU和主存之间。在进行运算的时候,CPU将需要的数据映射一份在缓存中,然后直接操作位于缓存中的数据,操作完毕后再将缓存中的数据写回到主存。这在单线程环境中是没有任何问题的。但是在多线程环境中就大不同了。 
(缓存是指在内存中划分出一块区域用于存放常使用的输入输出数据,以缓解CPU与外设处理速度不匹配的问题)
假设现在有这样的一个场景:有两个线程thread1和thread2,他们都在操作位于主存上的一个数据int a=2(具体操作为读取a的值并执行一个自增操作)。逻辑上正确的结果:应当是最后a=4。但可能有这样的情况,thread1将a=2从主存映射到自己的工作内存上,自增后变成a=3,在将a=3从工作内存写回到主存之前,thread2也将a=2从从主存映射到自己的工作内存上,也自增后变成a=3。然后两个线程先后将a=3写回到主存上。显然,a=3不是我们想看到的。看,这就是一个常见的缓存一致性问题。两个线程对a的操作结果互不可见,thread1不知道thread2对a进行了自增,thread2也不知道thread1对a进行了自增。在多线程编程中就是会出现这样一致性的问题。(在JMM中,可以知道,内存分为主内存和工作内存,每个线程有自己 的工作内存,他们共享主内存)。 

因此我们要办法让线程对共享变量的操作结果互相可见,java语言中的volatile关键字就干了一件这样的事。使用volatile修饰的共享变量,当有线程修改了他的值的时候,他会立即强制将修改的值写回到主存,并通知其他使用该共享变量的线程:他们的缓存区中关于此变量的值已经失效。请重新从主存中读取。 
仔细阅读volatile干的事,一共有3点影响: 
1 将修改的值强制刷新到主存 
2 通知其他相关线程变量已经失效 
3 其它线程再使用变量的时候就会重新从主存读取
 
这就解决了JAVA并发编程中的可见性问题。 

可见性:当多个线程访问同一个共享变量的时候,一个线程对该共享变量的修改能够实时的被访问该共享变量的其他线程知晓。
继续说上面的那个例子,如果变量a被使用了volatile修饰,那么在thread1中,当a变为3的时候,就会强制刷新到主存。如果这个时候,thread2已经将a=2从从主存映射到缓存上,那么在对a进行自增操作以前,会重新到主存中读取a=3,然后自增到a=4,然后写回到主存。上面的过程很完美,但这样是否保证了a最终的结果一定是4呢?未必。 
++这个操作非原子,a=a+1 同样非原子,先读a 然后再写 a

继续说上面的那个例子,如果变量a被使用了volatile修饰,那么在thread1中,当a变为3的时候,就会强制刷新到主存。如果这个时候,thread2已经将a=2从从主存映射到缓存上并且已经做完了自增操作,此时a=3,那么最终主存中a的值为3。 

所以,如果我们想让a的最终值是4,仅仅保证可见性是不够的,还得保证原子性。也就是对于变量a的自增操作加锁,保证任意一个时刻只有一个线程对a进行自增操作。可以说volatile是一种“轻量级的锁”,它能保证锁的可见性,但不能保证锁的原子性。
volatile变量的一种典型用法,就是用于那些状态的标记,比如: (这是一个最典型的应用,主要用于单例模式)

[java] view plaincopy
  1. volatile boolean flag=false;
  2. while(!flag){
  3. doSomething();
  4. }

在其他线程中,可能会修改flag的值为true,代表退出循环。如果不使用volatile修饰flag,可能在flag被回收之后,主线程还没收到其值改变的消息。这是volatile的一种典型应用。

转载于:https://www.cnblogs.com/silyvin/p/9106786.html

JAVA并发-从缓存一致性说volatile 讲的很好相关推荐

  1. Java并发编程:JMM和volatile关键字

    Java内存模型 随着计算机的CPU的飞速发展,CPU的运算能力已经远远超出了从主内存(运行内存)中读取的数据的能力,为了解决这个问题,CPU厂商设计出了CPU内置高速缓存区.高速缓存区的加入使得CP ...

  2. Java并发机制底层实现原理-volatile

    章节目录 volatile的实现原理与应用 1.volatile的实现原理与应用 Java source code->Java class->JVM->汇编指令->cpu执行 ...

  3. Java并发编程(三)volatile域

    相关文章 Java并发编程(一)线程定义.状态和属性 Java并发编程(二)同步 Android多线程(一)线程池 Android多线程(二)AsyncTask源代码分析 前言 有时仅仅为了读写一个或 ...

  4. Java并发机制深究1-synchronized和volatile

    在多线程并发编程中,synchronized和volatile都是很重要的,volatile是轻量级的synchronized.在多处理器编程中保证共享变量的统一性. 1.volatile的使用和原理 ...

  5. 进阶笔记——java并发编程三特性与volatile

    欢迎关注专栏:Java架构技术进阶.里面有大量batj面试题集锦,还有各种技术分享,如有好文章也欢迎投稿哦.微信公众号:慕容千语的架构笔记.欢迎关注一起进步. 前言 前面讲过使用synchronize ...

  6. 【Java并发编程:volatile关键字之解析】

    Java并发编程:volatile关键字解析 - Matrix海子 - 博客园 在Java 5之前,volatile是一个备受争议的关键字:因为在程序中使用它往往会导致出人意料的结果.在Java 5之 ...

  7. Java并发——volatile关键字的核心

    前言 在Java并发的话题中,volatile关键字一定是绕不开的话题.Java程序员都知道,volatile关键字的使用方式,以及它的特性:保证变量在内存中的可见性,但不保证原子性.Java的J.U ...

  8. Java并发编程最佳实例详解系列

    Java并发编程最佳实例详解系列: Java并发编程(一)线程定义.状态和属性 Java并发编程(一)线程定义.状态和属性 线程是指程序在执行过程中,能够执行程序代码的一个执行单元.在java语言中, ...

  9. java面试-Java并发编程(六)——线程间的通信

    多条线程之间有时需要数据交互,下面介绍五种线程间数据交互的方式,他们的使用场景各有不同. 1. volatile.synchronized关键字 PS:关于volatile的详细介绍请移步至:Java ...

最新文章

  1. 浅谈压缩感知(二十一):压缩感知重构算法之正交匹配追踪(OMP)
  2. Algs4-1.5.4给出id[]和sz[]的内容与次数
  3. 【Lucene4.8教程之四】分析
  4. java table修改指定行_(变强、变秃)Java从零开始之JQuery购物车功能实操
  5. JAVA垃圾回收器的介绍
  6. 自然语言处理hanlp的入门基础
  7. 使用maven构建项目候,jar包错误的解决办法
  8. java 映射数组_Java中的数组,列表,集合,映射,元组,记录文字
  9. 公司电脑监控软件_公司电脑监控软件,如何限制公司电脑网络游戏
  10. hadoop window 搭建
  11. volatile关键字(转)
  12. python如何收集数据库_利用Python操作mysql数据库
  13. QTP教程入门到高级(转)
  14. DFI(Deep/DynamicFlow Inspection,深度/动态流检测)
  15. Learning Standard C++ as a New Language ( By Bjarne Stroustrup )
  16. 2021年职业院校技能大赛“网络安全”项目江西省A模块
  17. matlab矩阵转入tecplot,[转载]tecplot编辑自己想要的变量
  18. 线程安全,线程同步,解决线程同步问题
  19. 2022/1/23(每周总结)
  20. TaefTestParser, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

热门文章

  1. Webpack安装及打包js、css文件示例
  2. python字符串截取:截取yaml文件名后3个字符
  3. Java客户端操作HBase:插入数据(逐条插入与批量插入)代码示例
  4. 使用pil读取gif图有些位置为黑色_使用 Pillow 快速创建 GIF 动图
  5. 浅析Java线程的三种实现
  6. 泛函分析——赋范线性空间定义的概念
  7. 6.0 《数据库系统概论》之关系数据库的规范化理论(数据依赖对表的影响[插入-删除-修改-冗余]、1NF-2NF-3NF-BCNF-4NF、函数依赖与多值依赖)
  8. 内存编程 c语言 c,C语言编程入门之内存管理
  9. python 生成pdf收据_python如何与以太坊交互并将区块链信息写入SQLite
  10. Linux信号列表(非实时信号和实时信号)