一、前言

在java多线程编程中,volatile可以用来定义轻量级的共享变量,它比synchronized的使用成本更低,因为它不会引起线程上下文的切换和调度。所谓知己知彼、百战不殆。本文从JVM内存模型角度,探讨volatile的实现原理。在明白了volatile的实现原理后,再回过头来使用它,会有一种一览众山小的感觉吧,使用起来会更加得心应手。

二、Java内存模型(JMM)

1、并发编程关键问题

多线程编程涉及到两个关键问题,线程之间的通信与同步。通信是指线程之间传递信息,同步是指控制线程操作的执行顺序。通过共享内存或者消息通知这两种方法,可以实现通信或同步。基于共享内存的线程通信是隐式的,线程同步是显式的;而基于消息通知的线程通信是显式的,线程同步是隐式的。JAVA是前者,即基于共享内存的隐式线程通信、显式线程同步。

2、happens-before模型

JMM呈现给程序员的模型是happens-before模型,即:

顺序规则:(单)线程中的写操作的结果,happens before于于任意后续操作。

锁规则: 锁的解锁,happens before于于锁的获取或加锁。

volatile变量规则:volatile写操作,happens before于后续该变量的读操作是可见的。

传递性:A操作happens before于B操作,B操作happens before于C操作,则A操作happens before于C操作

这儿的happens-before,并不是指操作先于后续操作执行,而是指操作结果对于后续结果是可见的。

3、可见性

在JMM中,每个线程的内存由两层构成:线程的“本地内存”、“主内存”。“本地内存”是JMM的一个抽象,本身是不存在的,它包括缓存、寄存器、写缓冲区、编译器及CPU的优化等。共享变量存放在“主内存”中,“本地内存”中存放的是共享变量的副本。当线程中发生对共享变量的写操作时,并不是直接写到“主内存”中的,而是先写到“本地内存”的写缓冲区中,只有当刷新(flush)到主内存后,才可能被其它线程加载到其“本地内存”中,此时我们说该共享变量是对其它线程“可见”的,反之如果没有刷新(flush)到主内存,就是对于其它线程“不可见”的。

JMM就是通过控制主内存与每个线程的本地内存之间的交互,来为Java程序员提供可见性的保证的

三、volatile类型的内存语义

happens-before规则提供了对volatile变量可见性的保证,即volatile变量的写操作,对后续任意对该变量的读操作是可见的。

四、volatile类型的JMM实现

再深入一些,JMM是如何实现happens-before模型中的volatile规则的呢?是通过限制这两种操作的重排序实现的。

重排序规则

第二个操作

第一个操作

volatile读

volatile写

普通读/写

volatile读

禁止重排序(1)

禁止重排序(2)

禁止重排序(3)

volatile写

禁止重排序(4)

禁止重排序(5)

-

普通读/写

-

禁止重排序(6)

-

(1) 第一个操作是volatile读时,不可以重排序,否则读出来的结果,可能是被修改过了的。

(2)(5)(6),第二个是volatile写时,所有操作都不可以被重排序于其后面,因为要确保其写的结果对于后续操作可见。

五、volatile类型使用的注意事项

多个volatile操作或复合操作,整体上不具有有序性

适用于对volatile变量的写操作很少而读操作很多的环境

java虚拟机内存模型种类_深入理解volatile类型——从Java虚拟机内存模型角度相关推荐

  1. java从内存角度理解类变量_深入理解volatile类型——从Java虚拟机内存模型角度...

    一.前言 在java多线程编程中,volatile可以用来定义轻量级的共享变量,它比synchronized的使用成本更低,因为它不会引起线程上下文的切换和调度.所谓知己知彼.百战不殆.本文从JVM内 ...

  2. java虚拟机和内存的关系_深入理解java虚拟机(linux与jvm内存关系)

    本文转载自美团技术团队发表的同名文章 https://tech.meituan.com/linux-jvm-memory.html 一, linux与进程内存模型 要理解jvm最重要的一点是要知道jv ...

  3. java jvm垃圾回收算法_深入理解JVM虚拟机2:JVM垃圾回收基本原理和算法

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 喜欢的话麻烦点下Star哈 文章将同步到我的个人博客: www.how ...

  4. 深入java虚拟机 第四版_深入理解Java虚拟机-常用vm参数分析

    Java虚拟机深入理解系列全部文章更新中... https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-java-nei-cun-qu-yu- ...

  5. java中对象的生存期_深入理解Java虚拟机-判断对象是否存活算法与对象引用

    我们知道Java中的对象一般存放在堆中,但是总不能让这些对象一直占着内存空间,这些对象最终都会被回收并释放内存,那么我们如何判断对象已经成为垃圾呢?这篇文章会提出两种算法解决这个问题.另外,本文还要谈 ...

  6. java中实现具有传递性吗_Java中volatile关键字详解,jvm内存模型,原子性、可见性、有序性...

    一.Java内存模型 想要理解volatile为什么能确保可见性,就要先理解Java中的内存模型是什么样的. Java内存模型规定了所有的变量都存储在主内存中.每条线程中还有自己的工作内存,线程的工作 ...

  7. 深入jvm虚拟机第4版_深入理解JVM虚拟机

    自动内存管理机制 Java虚拟机原理 所谓虚拟机,就是一台虚拟的机器.他是一款软件,用来执行一系列虚拟计算指令,大体上虚拟机可以分为 系统虚拟机和程序虚拟机, 大名鼎鼎的Visual Box.Vmar ...

  8. java中io是什么_深入理解Java中的IO

    深入理解Java中的IO 转载自:http://blog.csdn.net/qq_25184739/article/details/51205186 本文的目录视图如下: Java IO概要 a.Ja ...

  9. svchost占用内存过高_是什么导致你的Java服务器内存和CPU占用过高呢

    一.内存占用过高 1.造成服务器内存占用过高只有两种情况:内存溢出或内存泄漏 (1)内存溢出:程序分配的内存超出物理内存的大小,导致无法继续分配物理内存,出现OOM报错. (2)内存泄漏:不再调用的对 ...

最新文章

  1. 使用服务器测量网站性能,使用服务器时序测量网站性能
  2. JustOj 1486: Hello, world!
  3. 阿里云定时任务并自动释放
  4. 笨方法“学习python笔记之转义序列
  5. Python异常捕获及自定义异常类
  6. 系统权限安全责任书_权限越大,责任越大
  7. 灰色关联分析_R语言使用灰色关联分析(Grey Relation Analysis,GRA)中国经济社会发展指标...
  8. 一本通1594涂抹果酱
  9. iOS searchbar拼音和汉字搜索全国城市
  10. eXtremeComponents文档
  11. 扫盲:什么是steam令牌验证器?哪些行为会触发steam交易限制
  12. 0ctf_2017_babyheap
  13. 网站域名空间服务器,网站 域名 空间 服务器
  14. 【Linux】Linux文件锁
  15. React中使用SWR处理数据请求
  16. 兼容IE系列浏览器的CSS Hack
  17. 【Django】Python+Django 图文教程
  18. 使用TextPad一键编译运行C++程序和JAVA程序
  19. CBOW(Continuous Bag-of-Words)模型原理
  20. 有编程基础的人学python_有哪些适合零编程基础的人学习Python的书?

热门文章

  1. Android官方开发文档Training系列课程中文版:连接无线设备之网络服务搜索功能
  2. 十大双跨平台整体发展情况盘点
  3. 工业和信息化部办公厅关于公布2021年产业技术基础公共服务平台复核结果的通知
  4. ConcurrentHashMap源码剖析(1.8版本)
  5. 算法训练 Pollution Solution(计算几何)
  6. C++primer 13.6.2节练习
  7. 00002-两数之和-leetcode-1.暴力法(枚举法),2.哈希表法,目前更新了枚举法
  8. LeetCode 670 最大交换 (暴力+贪心、Python)
  9. python童年_300行Python代码实现俄罗斯方块,致敬逝去的童年
  10. ubuntu20.04安装Qt5.15.2并配置环境