云时代架构阅读笔记五——Java内存模型详解(一)
什么是Java内存模型
Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。在此之前,主流程序语言(如C/C++等)直接使用物理硬件和操作系统的内存模型,因此,会由于不同平台上内存模型的差异,有可能导致程序在一套平台上并发完全正常,而在另外一套平台上并发访问却经常出错,因此在某些场景下就不许针对不同的平台来编写程序。
Java内存模型即要定义得足够严谨,才能让Java的并发内存访问操作不会产生歧义;Java内存模型也必须定义地足够宽松,才能使得虚拟机的实现有足够的自由空间去利用硬件的各种特性来获取更好的执行速度。经过长时间的验证和修补,JDK1.5(实现了JSR-133)发布之后,Java内存模型已经成熟和完善起来了,一起来看一下。
主内存和工作内存
Java内存模型的主要目的是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。注意一下,此处的变量并不包括局部变量与方法参数,因为它们是线程私有的,不会被共享,自然也不会存在竞争,此处的变量应该是实例字段、静态字段和构成数组对象的元素。
Java内存模型规定了所有的变量都存储在主内存(Main Memory)中,每条线程还有自己的工作内存(Working Memory),线程的工作内存中保存了被该线程使用到的变量和主内存副本拷贝(注意这里绝不会是整个对象的拷贝,试想一个10M的对象,在每个用到这个对象的工作内存中有一个10M的拷贝,内存还受得了?也就是一些在线程中用到的对象中的字段罢了),线程对变量所有的操作(读取、赋值)都必须在工作内存中进行,而不能直接读写主内存中的变量。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。
内存间相互交互
关于主内存与工作内存之间具体的交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存之类的实现细节,Java内存模型中定义了以下8种操作来完成,虚拟机实现时必须保证下面体积的每一种操作都是原子的、不可再分的:
1、lock(锁定):作用于主内存中的变量,它把一个变量标识为一条线程独占的状态
2、unlock(解锁):作用于主内存中的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
3、read(读取):作用于主内存中的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用
4、load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中
5、use(使用):作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎,没当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行这个操作
6、assign(赋值):作用于工作内存中的变量,它把一个从执行引擎接收到的值赋值给工作内存中的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作
7、store(存储):作用于工作内存中的变量,它把工作内存中一个变量的值传送到主内存中,以便随后的write操作使用
8、write(写入):作用于主内存中的变量,它把store操作从工作内存中得到的变量值放入主内存的变量中
Java内存模型还规定了在执行上述8种基本操作时必须满足以下规则:
1、不允许read和load、store和write操作之一单独出现
2、不允许一个线程丢弃它的最近的assign操作,即变量在工作内存中改变了滞后必须把该变化同步回主内存
3、不允许一个线程无原因地把数据从线程的工作内存同步回主内存中
4、一个新的变量只能从主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量
5、一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁
6、如果对同一个变量执行lock操作,那将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化变量的值
7、如果一个变量事先没有被lock操作锁定,那就不允许对它进行unlock操作,也不允许去unlock一个被其他线程锁定的变量
8、对一个变量执行unlock操作之前,必须先把此变量同步回主内存中
云时代架构阅读笔记五——Java内存模型详解(一)的更多相关文章
- 云时代架构阅读笔记六——Java内存模型详解(二)
承接上文:云时代架构阅读笔记五——Java内存模型详解(一) 原子性.可见性.有序性 Java内存模型围绕着并发过程中如何处理原子性.可见性和有序性这三个特征来建立的,来逐个看一下: 1.原子性(At ...
- 云时代架构阅读笔记二——Java性能优化(二)
承接上文Java性能优化(一)https://www.cnblogs.com/guo-xu/p/11019267.html 4)尽量确定StringBuffer的容量 在说和这个标题相关之前,先说一下 ...
- 云时代架构阅读笔记一——Java性能优化(一)
Java语言学习了这么长时间之后,自己对于Java编程的一些细节还是稍微有点总结,正好根据云时代架构中<Java高级开发必会的50个性能优化的细节(珍藏版)>来叙述一些我和里面的点比较相符 ...
- 云时代架构阅读笔记七——Java多线程中如何使用synchronized关键字
关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...
- 深入理解JAVA虚拟机阅读笔记5——Java内存模型与线程
Java内存模型是定义线程共享的变量的访问规则(实例字段.静态字段和构成数组对象的元素),但不包括线程私有的局部变量和方法参数. 1.主内存与工作内存 Java内存模型规定,所有的变量都必须存储在主内 ...
- java内存模型详解
对于本篇文章,将从四个概念来介绍:内存模型基础,重排序,顺序一致性和happens-before 1.内存模型基础 在并发编程中,有两个关键问题:线程之间如何通信和如何同步.由此而引出了两种并发模型: ...
- Java 内存模型详解
概述 Java的内存模型(Java Memory Model )简称JMM.首先应该明白,Java内存模型是一个规范,主要规定了以下两点: 规定了一个线程如何以及何时可以看到其他线程修改过后的共享变量 ...
- 云时代架构阅读笔记十五——之前碰到的Java面试题
1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致. 2.Java有 ...
- 云时代架构阅读笔记十六——Hystrix理解
背景 分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务.如下图,对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,最终可能导致整个商品服 ...
随机推荐
- uniGUI之学习方法(18)
官方例子D:\Program Files\FMSoft\Framework\uniGUI\Demos\Desktop 在Design里Main上右键,View as Form看到变化的属性. 看出变化 ...
- 【快学springboot】8.JPA乐观锁OptimisticLocking
介绍 当涉及到企业应用程序时,正确地管理对数据库的并发访问是至关重要的.为此,我们可以使用Java Persistence API提供的乐观锁定机制.它导致在同一时间对同一数据进行多次更新不会相互干扰 ...
- alerm和pause
pause函数,会让进程进入阻塞状态,收到信号时,会中断这个阻塞的系统调用 alerm(s),会设置进程闹钟,在指定的时间后,进程会收到SIG_ALERM信号,收到这个信号时,可以中断pause阻塞调 ...
- ROS学习笔记11-写一个简单的服务和客户端(C++版本)
本文主要来源于:http://wiki.ros.org/ROS/Tutorials/WritingServiceClient%28c%2B%2B%29 写一个服务节点.在创建消息和服务中,我们创建了一 ...
- Android 如何从系统图库中选择图片
转:http://blog.csdn.net/tody_guo/article/details/7560270 这几天我都在做Android的App,同时学习它的API,我将分享一些我学到的东西,比如 ...
- H5禁止底部横向滚动条,使一个元素居中
1.禁止底部横向滚动条 选择元素设置样式 { overflow-y:auto; overflow-x:hidden } 2.元素居中 { margin-left:auto ; margin-right ...
- Linux CentOS7 VMware 文件和目录权限chmod、更改所有者和所属组chown、umask、隐藏权限lsattr/chattr
一.文件和目录权限chmod u User,即文件或目录的拥有者:g Group,即文件或目录的所属群组:o Other,除了文件或目录拥有者或所属群组之外,其他用户皆属于这个范围:a All,即全部 ...
- JDBC--获取数据库连接
1.JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统.统一的sQL数据库存取和操作的公共接口. 2.Java中的几种数据库存取技术: --1)JDBC直接 ...
- 「SCOI2010」连续攻击游戏
传送门 Luogu 解题思路 二分图匹配,关键是建图. 如果我们naive地直接把每个武器的两个属性分为两部建图的话,显然是跑不了的. 我们考虑把每一个武器的属性向它连边:\(a_i \rightar ...
- BugFix系列---开篇介绍
这个系列的文章,主要目的在于积累总结实际开发中遇到的错误,记录下来自己的解决思路,用来提升自己. 不出意外,应该会持续不断的记录更新,在整个开发openstack的过程中,抓住机会吸取开源界大牛的 ...