java并发---volatile关键字

原创 2018年04月16日 22:26:50

volatile的特性

  • 可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入
  • 原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性

volatile写-读建立的happens-before关系

从内存语义的角度来说,volatile的写-读与锁的释放-获取有相同的内存效果:volatile写和锁的释放有相同的内存语义;volatile读与锁的获取有相同的内存语义。

volatile写-读的内存语义

当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存。

  • 线程A写一个volatile变量,实质上是线程A向接下来将要读这个volatile变量的某个线程发出了(其对共享变量所做修改的)消息。
  • 线程B读一个volatile变量,实质上是线程B接收了之前某个线程发出的(在写这个volatile变量之前对共享变量所做修改的)消息。
  • 线程A写一个volatile变量,随后线程B读这个volatile变量,这个过程实质上是线程A通过主内存向线程B发送消息。

volatile内存语义的实现

JMM针对编译器制定的volatile重排序规则表

enter description here

举例来说,第三行最后一个单元格的意思是:在程序中,当第一个操作为普通变量的读或写时,如果第二个操作为volatile写,则编译器不能重排序这两个操作。

从表我们可以看出。

  • 当第二个操作是volatile写时,不管第一个操作是什么,都不能重排序。这个规则确保volatile写之前的操作不会被编译器重排序到volatile写之后。
  • 当第一个操作是volatile读时,不管第二个操作是什么,都不能重排序。这个规则确保volatile读之后的操作不会被编译器重排序到volatile读之前。
  • 当第一个操作是volatile写,第二个操作是volatile读时,不能重排序。
    为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。对于编译器来说,发现一个最优布置来最小化插入屏障的总数几乎不可能。为此,JMM采取保守策略。下面是基于保守策略的JMM内存屏障插入策略。

  • 在每个volatile写操作的前面插入一个StoreStore屏障。

  • 在每个volatile写操作的后面插入一个StoreLoad屏障。
  • 在每个volatile读操作的后面插入一个LoadLoad屏障。
  • 在每个volatile读操作的后面插入一个LoadStore屏障。

上述内存屏障插入策略非常保守,但它可以保证在任意处理器平台,任意的程序中都能得到正确的volatile内存语义。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011535387/article/details/79967721

Python并发管理

介绍Python的并发与调度机制,包括进程、线程、携程
  • 2018年02月07日 20:55

Java并发编程-正确理解volatile关键字的两层语义

关于关键字volatile可以说是Java虚拟机提供的轻量级的同步机制,但是它并不容易完全被正常、完整地理解,以至于许多程序员都不习惯去使用它,遇到需要处理多线程数据竞争问题的时候一律使用Synchr...
  • chenchaofuck1
  • chenchaofuck1
  • 2016-06-17 20:16:32
  • 1784

Android学习笔记六十二:Java并发编程:volatile关键字解析

出处:http://easygeek.com.cn/article/R7NvY3.html?ref=myread volatile这个关键字可能很多朋友都听说过,或许也都用过。在...
  • wuhenyouyuyouyu
  • wuhenyouyuyouyu
  • 2016-06-03 09:38:23
  • 422

聊聊并发(一)深入分析Volatile的实现原理

原文发表于InfoQ:http://www.infoq.com/cn/articles/ftf-java-volatile 引言 在多线程并发编程中synchronized和Volatil...
  • tenfyguo
  • tenfyguo
  • 2014-05-04 19:02:55
  • 6773

java volatile关键字(及使用场景)

当一个变量被定义为volatile之后,就可以保证此变量对所有线程的可见性,即当一个线程修改了此变量的值的时候,变量新的值对于其他线程来说是可以立即得知的。可以理解成:对volatile变量所有的写操...
  • x_i_y_u_e
  • x_i_y_u_e
  • 2016-02-24 10:55:24
  • 2693

java中的volatile关键字的功能详解

Cookie的应用场景: 1,记录用户的登陆状态,提示用户是否记住密码; 2,购物车购物功能; 我们知道,在web开发过程中,我们都要和cookie打交道,有时候离开了cookie还真玩不转。co...
  • reggergdsg
  • reggergdsg
  • 2015-12-11 22:01:24
  • 2599

Java并发编程系列之四:锁与volatile的内存语义

前言在前面的文章中已经提到过volatile关键字的底层实现原理:处理器的LOCK指令会使得其他处理器将缓存刷新到内存中(确切说是主存)以及会把其他处理器的缓存设置为无效。这里的内存语义则说的是在JM...
  • u011116672
  • u011116672
  • 2015-12-02 13:47:12
  • 1644

Java并发——线程同步Volatile与Synchronized详解

Java面试——线程同步volatile与synchronized详解 0. 前言面试时很可能遇到这样一个问题:使用volatile修饰int型变量i,多个线程同时进行i++操作,这样可以实现线程安全...
  • SEU_Calvin
  • SEU_Calvin
  • 2016-08-30 19:09:16
  • 18339

Java 关键字volatile 与 synchronized 作用与区别

1,volatile    volatile告诉jvm, 它所修饰的变量不保留拷贝,直接访问主内存中的。   在Java内存模型中,有main memory,每个线程也有自己的memory (例如...
  • HGuang_ZJH
  • HGuang_ZJH
  • 2014-04-13 23:10:42
  • 4264

Java线程安全之volatile关键字

我们知道在多线程的场景下,线程安全是必须要着重考虑的。Java语言包含两种内在的同步机制:同步块(synchronize关键字)和 volatile 变量。但是其中 Volatile 变量虽然使用简单...
  • Roy_70
  • Roy_70
  • 2017-04-07 10:37:02
  • 3825
收藏助手
不良信息举报
您举报文章:java并发---volatile关键字
举报原因:
原因补充:

(最多只允许输入30个字)