volatile关键字的两层语义
  一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
  1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
  2)禁止进行指令重排序。
根据volatile的语义,我们可以看到,volatile主要针对的是并发三要素(原子性,可见性和有序性)中的后两者有实际优化作用。
可见性:
  线程本身并不直接与主内存进行数据的交互,而是通过线程的工作内存来完成相应的操作。这也是导致线程间数据不可见的本质原因。因此要实现volatile变量的可见性,直接从这方面入手即可。对volatile变量的写操作与普通变量的主要区别有两点:

  (1)修改volatile变量时会强制将修改后的值刷新的主内存中。
  (2)修改volatile变量后会导致其他线程工作内存中对应的变量值失效。因此,再读取该变量值的时候就需要重新从读取主内存中的值。
  通过这两个操作,就可以解决volatile变量的可见性问题。
有序性:
  volatile会触发jvm的内存屏障策略
  
内存屏障策略:
(1)LoadLoad 屏障
  执行顺序:Load1—>Loadload—>Load2
  确保Load2及后续Load指令加载数据之前能访问到Load1加载的数据。
(2)StoreStore 屏障
  执行顺序:Store1—>StoreStore—>Store2
  确保Store2以及后续Store指令执行前,Store1操作的数据对其它处理器可见。
(3)LoadStore 屏障
  执行顺序: Load1—>LoadStore—>Store2
  确保Store2和后续Store指令执行前,可以访问到Load1加载的数据。
(4)StoreLoad 屏障
  执行顺序: Store1—> StoreLoad—>Load2
  每次对volatile进行读写操作,根据上述表格,会触发对应的CPU指令,从线程内存缓冲区将之前更改的变量刷入主存。
  简单来说,volatile会在一定程度上影响jvm指令集的优化策略,在volatile之前和之后的指令集不会乱序越过volatile变量执行。暂时volatile之前和之后的指令集在没有关联性的前提下,jvm可以乱序执行。
  jvm的volatile策略,在一定程度上,打折扣地实现了jvm的happens-before原则(先行发生原则),如下所述。
 
  • 程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
  • 锁定规则:一个unLock操作先行发生于后面对同一个锁额lock操作
  • volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作
  • 传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C
  • 线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作
  • 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生
  • 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行
  • 对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始

volatile常见使用场景:

(1)状态标记量

(2)单例模式一次性安全发布

(3)低开销读写锁

参考文档:
《Java并发编程:Volatile关键字解析》http://www.cnblogs.com/dolphin0520/p/3920373.html
《Java多线程:volatile变量,happens-before关系及内存一致性》http://www.importnew.com/17149.html
《Java并发编程:volatile的使用及其原理》http://www.cnblogs.com/paddix/p/5428507.html
《Java理论与实践:正确使用Volatile变量》https://www.ibm.com/developerworks/cn/java/j-jtp06197.html

Java并发编程 Volatile关键字解析的更多相关文章

  1. Java 并发:volatile 关键字解析

    摘要: 在 Java 并发编程中,要想使并发程序能够正确地执行,必须要保证三条原则,即:原子性.可见性和有序性.只要有一条原则没有被保证,就有可能会导致程序运行不正确.volatile关键字 被用来保 ...

  2. java并发系列(六)-----Java并发:volatile关键字解析

    在 Java 并发编程中,要想使并发程序能够正确地执行,必须要保证三条原则,即:原子性.可见性和有序性.只要有一条原则没有被保证,就有可能会导致程序运行不正确.volatile关键字 被用来保证可见性 ...

  3. Java并发编程volatile关键字

    volatile理解 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和volatile 关键字机制.volatile具有synchronized关键字的“可见性”,vo ...

  4. java并发编程 volatile关键字 精准理解

    1.volatile的作用 一个线程共享变量(类的成员变量.类的静态成员变量等)被volatile修饰之后,就具有以下作用: 1)并发中的变量可见性(不同线程对该变量进行操作时的可见性),即一个线程修 ...

  5. 一起来看看java并发中volatile关键字的神奇之处

    并发编程中的三个概念: 1.原子性 在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作,即这些操作是不可被中断的,要么执行,要么不执行. 2.可见性 对于可见性,Java提供了volati ...

  6. java并发:volatile关键字

    java并发需要保证原子性,可见性,有序性. http://www.cnblogs.com/expiator/p/9226775.html 一.volatile关键字作用如下: 1.volatile关 ...

  7. Java 并发编程——volatile与synchronized

    一.Java并发基础 多线程的优点 资源利用率更好 程序设计在某些情况下更简单 程序响应更快 这一点可能对于做客户端开发的更加清楚,一般的UI操作都需要开启一个子线程去完成某个任务,否者会容易导致客户 ...

  8. Java多线程编程——volatile关键字

    (本篇主要内容摘自<Java多线程编程核心技术>) volatile关键字的主要作用是保证线程之间变量的可见性. package com.func; public class RunThr ...

  9. Java并发编程--Volatile详解

    摘要      Volatile是Java提供的一种弱同步机制,当一个变量被声明成volatile类型后编译器不会将该变量的操作与其他内存操作进行重排序.在某些场景下使用volatile代替锁可以减少 ...

随机推荐

  1. Microsoft Visual C++ Package Server 已停止工作

    使用vs2010时,有时会提示“Microsoft Visual C++ Package Server 已停止工作”,是否需要关闭程序或者调试程序. CPkgSrv 是关于Visual Studio ...

  2. JSP是什么?

    JSP      [1] 简介           > HTML                - HTML擅长显示一个静态的网页,但是不能调用Java程序.           > Se ...

  3. JavaJavaScript小问题系列之JSON解析

    1.错误消息及截图 这个很搞笑也很纠结,今天一开发妹子,发现一个问题: 服务端返回字符串"{\"phone\":\"15000000000\"}&qu ...

  4. SQL查询四舍五入 解决方法

    方法1: SELECT CAST('123.456' as decimal) 将会得到 123(小数点后面的将会被省略掉). 如果希望得到小数点后面的两位. 则需要把上面的改为 SELECT CAST ...

  5. 【Spring 核心】AOP 面向切面编程

    一.什么是面向切面编程? 二.通过切点来选择连接点 三.使用注解创建切面 四.在XML中声明切面 五.注入AspectJ切面

  6. golang的Channel

    golang的Channel Channel 是 golang 一个非常重要的概念,如果你是刚开始使用 golang 的开发者,你可能还没有真正接触这一概念,本篇我们将分析 golang 的Chann ...

  7. 将Windows系统默认的Administrator帐号改名为我们自定义的名称

    将Windows系统默认的Administrator帐号改名为我们自定义的名称.. ---------如何将Administrator帐号改名为我们自定义的名称:Win+R--->>输入g ...

  8. JavaWeb(七)Cookie,EL表达式,标准标签库

    Cookie Cookie概述 Cookie译为小型文本文件或小甜饼,Web应用程序利用Cookie在客户端缓存服务器端文件.Cookie是以键值对形式存储在客户端主机硬盘中,由服务器端发送给客户端, ...

  9. 并发是个什么鬼之同步工具类CountDownLatch

    扯淡 写这篇文章,我先酝酿一下,实不相瞒,脱离底层太久了,更确切的情况是,真没曾认真研究过.就目前来说,很多框架包括工具类已经把实现封装的很深,你只需轻轻的调用一下API,便不费半点力气.以至于大家会 ...

  10. Spring详解(一)------概述

    本系列教程我们将对 Spring 进行详解的介绍,相信你在看完后一定能够有所收获. 1.什么是 Spring ? Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开 ...