volatile的特性

理解volatile特性的一个好方法是把对volatile变量的单个读/写,堪称是使用同一个锁对这些单个读/写操作做了同步。

锁的happens-before规则保证释放锁和获取锁的两个线程之间的内存可见性,这意味着对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。

锁的语义决定了临界区代码的执行具有原子性。即使是64位的long型和double型变量,只要它是volatile变量,对该变量的读/写就具有原子性。如果是多个volatile操作或类似于volatile++这种复合操作,这些操作整体上不具有原子性。

volatile变量自身具有下列特性。

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

volatile写-读的内存语义

volatile写的内存语义如下。

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

volatile读的内存语义如下。

当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。

对volatile写和volatile读的内存语义做个总结。

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

volatile内存语义的实现

volatile重排序规则表

从表中我们可以看出。

  • 当第二个操作是volatile写时,不管第一个操作是什么,都不能重排序。
  • 当第一个操作是volatile读时,不管第二个操作是什么,都不能重排序。
  • 当第一个操作是volatile写,第二个操作是volatile读时,不能重排序。

保守策略下,volatile写插入内存屏障后生成的指令序列示意图:

在保守策略下,volatile读插入内存屏障后生成的指令序列示意图:

JSR-133为什么要增强volatile的内存语义

严格限制编译器和处理器对volatile变量与普通变量的重排序,确保volatile的写-读和锁的释放-获取具有相同的内存语义。

在功能上,锁比volatile更强大;在可伸缩性和执行性能上,volatile更加优势。

volatile的内存语义的更多相关文章

  1. JAVA锁和volatile的内存语义&volatile的使用场景

    JAVA锁的内存语义 当线程释放锁时,JMM(Java Memory Model)会把该线程对应的本地内存中的共享变量刷新到主内存中. 当线程获取锁时,JMM会将该线程对应的本地内存置为无效.从而使得 ...

  2. Java内存模型-volatile的内存语义

    一 引言 听说在Java 5之前volatile关键字备受争议,所以本文也不讨论1.5版本之前的volatile.本文主要针对1.5后即JSR-133针对volatile做了强化后的了解. 二 vol ...

  3. Java并发编程原理与实战四十二:锁与volatile的内存语义

    锁与volatile的内存语义 1.锁的内存语义 2.volatile内存语义 3.synchronized内存语义 4.Lock与synchronized的区别 5.ReentrantLock源码实 ...

  4. volatile的内存语义与应用

    volatile的内存语义 volatile的特性 理解volatile特性的一个好方法是把对volatile变量的单个读/写,堪称是使用同一个锁对这些单个读/写操作做了同步. 锁的happens-b ...

  5. 【java多线程系列】java中的volatile的内存语义

    在java的多线程编程中,synchronized和volatile都扮演着重要的 角色,volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的可见性,可见性指的是当一 ...

  6. Java-内存模型 final 和 volatile 的内存语义

    前提:内存屏障 内存屏障(Memory Barrier)与内存栅栏(Memory Fence)是同一个概念. 用于阻止指令重排序.保证了特定操作的执行顺序和某些变量的内存可见性. JMM 内存屏障分为 ...

  7. 内存屏障和volatile内存语义的实现

    趁周末,把以前的书拿出来,再翻一番,顺便做个笔记: 内存屏障:用来控制和规范cpu对内存操作的顺序的cpu指令. 内存屏障列表: 1.loadload:确保“前者数据装载”先于“后者装载指令”: 2. ...

  8. volatile内存语义

    全面理解Java内存模型(JMM)及volatile关键字 volatile的内存语义 Volatile读写所建立的happens-before关系Volatile读写的内存语义 锁: 获取和释放Vo ...

  9. volatile 和锁的内存语义

    一.volatile 的内存语义 1. volatile 的特性 volatile变量自身具有以下特性: 可见性 :对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后 ...

随机推荐

  1. SqlBulkCopy简单封装,让批量插入更方便

    关于 SqlServer 批量插入的方式,前段时间也有大神给出了好几种批量插入的方式及对比测试(http://www.cnblogs.com/jiekzou/p/6145550.html),估计大家也 ...

  2. ansible一键部署k8s单机环境

    一.虚拟机准备 干净的Centsot7.4.4G内存.2个CPU 最小化安装,最好带虚拟化 二.执行初始化脚本 注意:脚本中配置静态网卡根据实际网卡名称配置,我用的是ens33 可以用 sed -i ...

  3. 测试网站页面网速的一个简单Python脚本

    无聊之余,下面分享一个Python小脚本:测试网站页面访问速度 [root@huanqiu ~]# vim pywww.py #!/usr/bin/python # coding: UTF-8 imp ...

  4. Python下操作Memcache/Redis/RabbitMQ说明

    一.MemcacheMemcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的.需要频繁访 ...

  5. 安装mysql解压版时遇到的错误

    平常都是使用exe安装mysql,今天使用解压包的,遇到了一系列问题: 环境:win10 mysql版本:mysql-5.7.21-winx64 开始一直用该网页的教程 https://www.cnb ...

  6. 关于git的一些体会:

    周忠贤github链接:https://github.com/zhouzhongxian git学习心得:通过这次的学习,体会到了许多东西只要你用心去做,就没有什么做不成,,这次体会到了网上学习的重要 ...

  7. leetcode 730 Count Different Palindromic Subsequences

    题目链接: https://leetcode.com/problems/count-different-palindromic-subsequences/description/ 730.Count ...

  8. shell脚本--文件查找之find命令

    首先是通过文件名称来查找,需要使用一个-name参数. 查询以  .txt结尾的文件,和以 t 开头的文件: ubuntu@ubuntu:~/test$ ls one.txt three.txt tw ...

  9. Fixed the bug:while running alert/confirm in javascript the chrome freezes

    显示高级设置... 系统  -> 使用硬件加速模式(如果可用) 操作系统如果不支持硬件加速,却启动此项,就悲催了.小伙伴们可别瞎点了,太吃亏. 现象alert/confirm一执行,chrome ...

  10. laravel 数据库获取值的常用方法

    ---恢复内容开始--- find($id) 需要一个主键$id并返回一个模型对象,若不存在则返回null findOrFail($id) 需要一个主键$id并返回一个模型对象,若不存在则发生错误,抛 ...