java 内存模型
翻译自wiki百科:https://en.wikipedia.org/wiki/Java_memory_model
没找到直接在wiki上编辑中文的页面,我就在这翻译下,自己学习用。
java内存模型描述了线程在java编程中如何和内存交互。连同单线程执行代码描述,这个内存模型提供java编程语言的含义。
原始的java内存模型是在1995年发展的,被广泛看作破坏,阻止很多运行时的优化的并且对代码安全不提供足够强的保证的。
环境
java 编程语言和平台提供线程功能。线程之间的同步对开发者很难理解。难点在于java应用程序可以在很多的处理器和操作系统上运行。为了可以总结出一个程序的行为,java的设计者决定清楚的定义所有程序可能的行为。
在现代的平台上,编写完的代码通常是没有被执行的。它被编译器,处理器和内存系统重新整理以达到最高的性能。一个多处理器的架构,单独的处理器们必须有它们自己的和主内存不同步的本地缓存。要求多线程保持完美的同步通常是不受欢迎的,因为它通常是很消耗性能的。这意味着在一定的时间里不同的线程中同一共享内存也许会有不同的值。
在单线程环境中,很容易解释代码的执行。传统的方法要求系统实现单线程独立的“as-if-serial”语义。当一个独立的线程执行的时候,它会如同顺序执行程序,即使这行行为发生的是无序的。
如果单线程执行指令是乱序的,其他的线程也许会意识到这些指令执行是无序的即使不影响第一个线程的语意。例如考虑两个以下指令的线程,同步执行,x,y变量都被初始化为0:
Thread1 | Thread2 |
x=1; | int r1 = y; |
y=2; | int r2 = x; |
如果没有重排,并且线程2中读y的值为2.那么随后读取的x应该是1.因为对x的写早于对y的写。如果对写进行了重排,那么读Y可以返回2,而读取x可以返回0。
这个java内存模型定义了多线程允许的行为,同时上面的读的情况是可能存在的。它在线程和主内存中为了达到一致和可靠的的应用产生了执行时间的约束。通过这个约束,使代码在多线程环境中执行变成了可能,即使面对动态编译器,处理器和缓存的优化。
内存模型
执行单线程的时候,规则很简单,java编程规范要求jvm遵守within-thread as-if-serial 的语义。这个运行时(通常是指动态编译,处理器和内存的子系统)对于引入任何有用的执行优化只要线程隔离的结果保证是准确的同时他也会有所有程序的声明顺序执行。
对于as-if-serial 语义有一个警告:不要阻止不同的线程拥有不同的数据面。内存模型提供很清楚的关于在数据被读取时哪些值可以返回的指南。基本的原则反应了单独的操作可以乱序,只要这个线程的as-if-serial 语义没有被违反,并且线程之间通讯的行为比如获取释放一个锁,确保这些行为优先发生并对其他的线程可见。比如在释放锁之前的行为应该可以被之后回收锁后的事情是可见的并且是有序的。
有可能这里有一个部分有序被称为happens-before order 在所有的行为通过程序执行。这个happens-before 顺序对程序顺序进行归类;如果一个动作在另外一个动作之前发生,它会在其他的在happens-before顺序中的动作之前发生。另外,释放和随后获取锁的行为组成了happens-before的连接。读被用来允许返回写的值,如果这个写是这个变量的最后一次写。
影响
java内存模型是第一次在流行语言中尝试复杂的内存模型。日渐流行的并发同步系统需要一个可以提供明确语义的技术和工具。从那以后对于内存模型的需要被广泛接受,像C++这些语言也开始提供。
后续可以查看:
Memory model(computing):https://en.wikipedia.org/wiki/Memory_model_(programming)
Java concurrency:https://en.wikipedia.org/wiki/Java_concurrency
--------------
果然翻译的很生硬,翻完了还是不太明白这里java内存模型是什么个模型,觉得是一个保证并发线程可以按照顺序来执行的工具,可是具体怎么实现的原理还是不太清楚。
还有一篇文章可以瞅瞅:
http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html
JSR 133 (Java Memory Model) FAQ
找了一个翻译它还不错的文章:
http://www.ticmy.com/?p=315
--------
上面的blog还有文章解释了之前翻译的几个概念:http://www.ticmy.com/?p=425
1.可见性--- 由于每个线程都有自己的工作空间,就看成每个线程自己在内存里面有一小段缓存吧,如果变量只是写在缓存里面,还没有写入主内存的话,其他线程是无法看到这个变量的改变的。
2. happens before 概念:java内存模型定义很多的happens before 规则。比如:
- An unlock on a monitor happens-before every subsequent lock on that monitor
这个 线程里面解锁监控器的操作以及之前全部的操作对后面的获取锁的操作的线程(包括同一个线程)都可见,理解下来就像是 编译器给我听好了,这个线程里面获取解锁操作之前 所有的变量都要写入主内存了,方便后面的操作来查看了。
还有一些实例的使用,挺好的文章,需要多瞅几遍了。
java 内存模型的更多相关文章
- JVM学习(3)——总结Java内存模型
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简 ...
- 浅析java内存模型--JMM(Java Memory Model)
在并发编程中,多个线程之间采取什么机制进行通信(信息交换),什么机制进行数据的同步? 在Java语言中,采用的是共享内存模型来实现多线程之间的信息交换和数据同步的. 线程之间通过共享程序公共的状态,通 ...
- JMM(java内存模型)
What is a memory model, anyway? In multiprocessorsystems, processors generally have one or more laye ...
- 《深入理解Java内存模型》读书总结
概要 文章是<深入理解Java内容模型>读书笔记,该书总共包括了3部分的知识. 第1部分,基本概念 包括"并发.同步.主内存.本地内存.重排序.内存屏障.happens befo ...
- Java内存模型深度解析:final--转
原文地址:http://www.codeceo.com/article/java-memory-6.html 与前面介绍的锁和Volatile相比较,对final域的读和写更像是普通的变量访问.对于f ...
- Java内存模型深度解析:volatile--转
原文地址:http://www.codeceo.com/article/java-memory-4.html Volatile的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特 ...
- Java内存模型深度解析:顺序一致性--转
原文地址:http://www.codeceo.com/article/java-memory-3.html 数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据 ...
- Java内存模型深度解析:基础部分--转
原文地址:http://www.codeceo.com/article/java-memory-1.html 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何 ...
- 深入理解java内存模型系列文章
转载关于java内存模型的系列文章,写的非常好. 深入理解java内存模型(一)--基础 深入理解java内存模型(二)--重排序 深入理解java内存模型(三)--顺序一致性 深入理解java内存模 ...
- Java内存模型深度解读
Java内存模型规范了Java虚拟机与计算机内存是如何协同工作的.Java虚拟机是一个完整的计算机的一个模型,因此这个模型自然也包含一个内存模型——又称为Java内存模型. 如果你想设计表现良好的并发 ...
随机推荐
- .net使用mvc模式开发web应用 模型与视图间的数据处理
http://www.cnblogs.com/JeffreyZhao/archive/2009/02/27/mvc-use-strong-type-everywhere.html#3427764 本文 ...
- gerrit 部署手册
概述 gerrit是谷歌开发用于安卓系统的代码审查的系统,目前已经开源.gerrti使用简单并友好.这里记录了gerrti的部署方法以及其中可能存在的陷阱和问题. 创建专属系统用户 Gerrit co ...
- myeclipse的web project中使用dom4j报错java.lang.ClassNotFoundException: org.dom4j.Document
在学习微信公众平台开发的过程中,参考了微信公众平台java开发详解(工程代码+解析)中的xml解析方法,是使用dom4j来解析的. 对于java中解析xml的方法,又参考了java解析xml的几种方式 ...
- Win7(32bit)下Qt5.5.0和OpenCV2.4.9环境的搭建
之前一直基于Windows平台(Win 7 32bit)使用VS2010做OpenCV的开发,现在开始学习在Windows 下使用Qt做OpenCV的开发.本文主要讲述Windows平台下(Win 7 ...
- [ubuntu] adb devices出现no permissions
简书排版 http://www.jianshu.com/p/46e8848c6646 今天把一款测试的华为手机带回家,发现无法联机调试 笔者操作系统是 ubuntu 14.04 如果是windows找 ...
- PHP中phar包的使用
PHP5.3之后支持了类似Java的jar包,名为phar.用来将多个PHP文件打包为一个文件. 首先需要修改php.ini配置将phar的readonly关闭,默认是不能写phar包的,includ ...
- final、finally、finalize的区别
看C#知识点的时候发现的问题 1.final 修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此一个类不能既被声明为 abstract的,又被声明为f ...
- 【转】Nginx服务器详细配置含注释
#使用的用户和组 user www www; #指定工作衍生进程数(一般等于CPU的总核数或总核数的两倍) worker_processes 8; #指定错误日志存放的路径,错误日志的记录级别可为de ...
- WPF Combobox样式
<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}&qu ...
- Java正则表达式的解释说明
1.字符x 字符 x.例如a表示字符a\\ 反斜线字符.在书写时要写为\\\\.(注意:因为java在第一次解析时,把\\\\解析成正则表达式\\,在第二次解析时再解析为\,所以凡是不是1 ...