注:本文主要参考自《深入理解Java虚拟机(第二版)》和《深入理解Java内存模型》

1、Java内存模型(JMM)

Java内存模型的主要目标:定义在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。

注意:上边的变量指的是共享变量(实例字段、静态字段、数组对象元素),不包括线程私有变量(局部变量、方法参数),因为私有变量不会存在竞争关系。

1.1、内存模型就是一张图:

说明:

  • 所有共享变量存于主内存
  • 每一条线程都有自己的工作内存(就是上图所说的本地内存)
  • 工作内存中保存了被该线程使用到的变量的主内存副本

注意:

  • 线程对变量的操作都要在工作内存中进行,不能直接操作主内存
  • 不同的线程之间无法直接访问对方的工作内存中的变量
  • 不同线程之间的变量的传递必须通过主内存

类比:(注意:主内存与工作内存只是一个概念,与堆栈内存没有关系,下边的类比只是帮助理解)

  • 主内存:对应于Java堆中的对象实例数据部分(注意:堆中还保存了对象的其他信息,eg.Mark Word、Klass Point和用于字节对其补白的填充数据)
  • 工作内存:对应于栈中的部分区域

1.2、8条内存屏障指令:

下面只列出6条与之后内容相关的,其余的查看《深入理解Java虚拟机》

  • lock:作用于主内存,把一个变量标识为一条线程独占的状态
  • unlock:作用于主内存,把一个处于锁定的变量解锁

下边四条是与volatile实现内存可见性直接相关的四条(store、write、read、load)

  • store:把工作内存中的变量的值传送到主内存中
  • write:把store操作从工作内存中得到的变量值放入到主内存的变量中
  • read:把一个变量的值从主内存中传输到线程的工作内存
  • load:把read操作从主内存中获取到的变量值放入工作内存的变量中去

注意:

  • 一个变量在同一时刻只允许一条线程对其进行lock操作
  • lock操作会将该变量在所有线程工作内存中的变量副本清空,否则就起不到锁的作用了
  • lock操作可被同一条线程多次进行,lock几次,就要unlock几次(可重入锁)
  • unlock之前必须先执行store-write
  • store-write必须成对出现(工作内存-->主内存)
  • read-load必须成对出现(主内存-->工作内存)

2、变量对所有线程的可见性

可见性:线程1对共享变量的修改能及时被线程2看到

2.1、共享变量不可见的原因

  • 共享变量更新后的值没有在工作内存和主内存之间及时更新
  • 线程交错执行
  • 指令重排序结合线程交错执行

2.2、实现共享变量及时更新的措施

线程1修改过共享变量后,将共享变量刷到主内存,然后,线程2从主内存读取该共享变量,将该共享变量载入到工作内存中

注意:在短时间内的高并发情况下,如果发生下列三种情况,则线程2就读不到线程1修改过的最新的值了,

  • 可能线程1根本来不及将修改过后的共享变量刷到主内存(这个时间非常短,但是还是有)的时候,线程2就已经读取了原有的主内存变量到其工作内存中。
  • 可能线程1虽然将修改过后的值刷到了主内存中,但是线程2的工作内存中的变量副本还没来得及从CPU刷新回来,所以线程2读取到的还是原来的工作内存中的变量副本
  • 可能线程1根本来不及将修改过后的共享变量刷到主内存的时候,同时,线程2的工作内存中的变量副本还没来得及从CPU刷新回来

注意:工作内存中的变量副本在使用之后,不会立刻消失掉,会一直存在,这样其值也一直不变,直到对其进行写操作或数据从CPU中刷新回来(类比volatile-read的作用)。

2.3、指令重排序:代码书写顺序与实际执行顺序不同(编译器或处理器为提高程序性能做的优化)

eg.

书写代码的顺序如下:

1         int a = 12;
2         int b = 13;
3         int c = a+b;

可能实际执行代码的顺序如下:

1         int b = 13;
2         int a = 12;
3         int c = a+b;

总结:本文大概介绍了一下Java内存模型以及与共享变量可见性的一些概念,为下边的volatile做准备。

分类: Java并发包类源码解析

Java内存模型与共享变量可见性相关推荐

  1. java map 内存可见性_JMM(一):初识Java内存模型

    在并发编程中,线程之间的通信是一个很关键的问题,而该问题解决方案主要可分为两大类:消息传递.共享内存.前者有以Erlang语言为代表的Actor模型,而后者中典型的则是Java语言.对于消息传递机制而 ...

  2. java 及时释放内存_JMM(一):初识Java内存模型

    在并发编程中,线程之间的通信是一个很关键的问题,而该问题解决方案主要可分为两大类:消息传递.共享内存.前者有以Erlang语言为代表的Actor模型,而后者中典型的则是Java语言.对于消息传递机制而 ...

  3. Java并发:线程共享变量可见性原理

    0.线程安全性:线程安全性包括两个方面,①可见性.②原子性. 0.1.线程之间的通信:线程的通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种共享内存和消息传递. (1)在 ...

  4. java内存模型 原子性_Java内存模型JMM 高并发原子性可见性有序性简介 多线程中篇(十)...

    JVM运行时内存结构回顾 在JVM相关的介绍中,有说到JAVA运行时的内存结构,简单回顾下 整体结构如下图所示,大致分为五大块 而对于方法区中的数据,是属于所有线程共享的数据结构 而对于虚拟机栈中数据 ...

  5. Java内存模型、volatile、原子性、可见性、有序性、happens-before原则

    目录 1.硬件的效率与一致性: 缓存一致性(Cache Coherence) 2.Java内存模型 2.1主内存与工作内存 2.2内存间的交互 2.3 volatile型变量的特殊规则 2.3.1 保 ...

  6. Java内存模型(JMM)详解-可见性volatile

    这里写自定义目录标题 Java内存模型(JMM)详解-可见性 什么是JMM JMM存在的意义 为什么示例demo中不会打印 i 的值 如何解决可见性问题 **深入理解JMM内存模型** JAVA内存模 ...

  7. 重点知识学习(8.2)--[JMM(Java内存模型),并发编程的可见性\原子性\有序性,volatile 关键字,保持原子性,CAS思想]

    文章目录 1.JMM(Java Memory Model) 2.并发编程的可见性 3.并发编程的有序性 4.并发编程的原子性 5.volatile 关键字 6.保持原子性: 加锁,JUC原子类 加锁 ...

  8. java基础—java内存模型(JMM)CPU架构、缓存一致性、重排序、JMM的实现、JMM保证可见性、有序性问题的详解

    java基础-JMM(CPU架构.JMM保证可见性.有序性) 文章目录 java基础-JMM(CPU架构.JMM保证可见性.有序性) CPU架构 说一说现在计算机存储器的结构层次 使用CPU缓存,会导 ...

  9. java内存模型按照线程隔离性_深入理解Java多线程与并发框(第③篇)——Java内存模型与原子性、可见性、有序性...

    一.Java内存模型 Java Memory Modle,简称 JMM,中文名称 Java内存模型,它是一个抽象的概念,用来描述或者规范访问内存变量的方式.因为各中计算机的操作系统和硬件不同,方式机制 ...

  10. java 线程 原子性_深入理解Java多线程与并发框架——Java内存模型与原子性、可见性、有序性...

    欢迎关注专栏<Java架构筑基>--专注于Java技术的研究与分享!Java架构筑基​zhuanlan.zhihu.comJava架构筑基--专注于Java技术的研究与分享! 后续文章将首 ...

最新文章

  1. Android 中Message,MessageQueue,Looper,Handler详解+实例
  2. 判断浮点数溢出的方法
  3. OpenCASCADE:Foundation Classes使用句柄编程
  4. 【数学题】男女的比例
  5. jQuery 实现一个简单的信息反馈或者信息收集的页面
  6. c#字符型转化为asc_C#字符串和ASCII码的转换
  7. Java怎么去最高分最低分,深入java虚拟机:原子操作ParkEvent和Parker
  8. java数组中重复_数组中重复的数字 java
  9. Python中列表的增、删、改、查、排序
  10. 第十七章 特殊成员_使用typedef简化函数指针的声明
  11. Java程序员必看的 13 本 Java 书籍
  12. FPGA学习——Vivado2017.4安装教程
  13. BT5的默认用户名和密码
  14. 您的计算机无法访问dota2服务器,一招解决DOTA2国服客户端无法启动问题
  15. scrapy爬虫-美图录
  16. 【社招】 中/高级C++ Developer - 美国顶尖交易公司Akuna Capital–上海
  17. 重装系统开机蓝屏0x0000007E错误但是可以进入安全模式
  18. html中的颜色代码详解及图示
  19. java 所得税计算_java个人所得税计算器
  20. 平板电脑触摸屏行业研究及十四五规划分析报告

热门文章

  1. SQL Server 两个时间段的差and时间截取到时分
  2. mysql 大事物commit慢造成全库堵塞问题
  3. (github精选)优秀的openSCAD项目image2surface
  4. javascript 正则
  5. 从Ibatis过渡到Mybatis-比较Mybaits较与Ibatis有哪些方面的改进
  6. python之6-1常用函数
  7. 幸福框架:可扩展的、动态的、万能的 编号生成器
  8. macvlan 详解
  9. Linux 内存管理(一)——地址空间
  10. L2-028 秀恩爱分得快(25 分)