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内存模型. 如果你想设计表现良好的并发 ...
随机推荐
- JavaWeb 学习004-增删改查的编写
完成了grade,student模块的 数据库连接部分,还需要不断重复这个过程,熟练掌握JDBC的编写. 在不断编写的过程中,加深理解代码. 下一步 1.biz层面的知识内容 2.还有就是登陆成功后跳 ...
- [转] Oracle sql 查询突然变慢 -- 案例分析
转自:http://jingyan.baidu.com/article/8275fc868ce57946a03cf692.html 一条sql突然执行变慢,耗时9秒,应用是不能改的,只能从数据库方面下 ...
- Oracle以及SDE维护常用命令-查看表空间等
之前现场反馈一个数据更新的问题,查看感觉是因为表空间满了导致的(错误在之前的博客随笔中写过),因此远程对服务器进行查看.个人平常都是通过Oracle客户端的Entreprise Manager Con ...
- UISegmentedControl 控件
一.创建 UISegmentedControl* mySegmentedControl = [[UISegmentedControl alloc]initWithItems:nil]; 是不是很奇怪没 ...
- 4. Prototype(原型)
意图: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 适用性: 当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者 为了避免创建一个与产品类层次平行的工厂类层次时:或者 当 ...
- [15]APUE:pipe / FIFO
管道 pipe 一.概述 管道(pipe / FIFO)是一种文件,属于 pipefs 文件系统类型,可以使用 read.write.close 等系统调用进行操作 其本质是内核维护了一块缓冲区与管道 ...
- 纯jsp用户登录系统
用纯jsp技术实现用户登录系统,需要用到三个.jsp文件.在文本目录下新建三个.jsp文件,分别命名为login.jsp,logincl.jsp和wel.jsp. 1.login.jsp文件用来放界面 ...
- 【温故Delphi】Win32API之CreateMutex
解决问题 如何让一个软件在一台机器上只能运行一个实例呢?这个问题用专业术语就是进程互斥.这个问题可以通过CreateMutex来解决. 进程互斥的核心思想:进程在启动时首先检查是否存在此进程实例,如果 ...
- c# GridView有关RowClick事件,可单击显示选中的row
//当前选定行 int i = this.gridView1.FocusedRowHandle; //选中行,列名为name的值 gridView1.GetRowCellDisplayText(i, ...
- response.setHeader()的用法
一秒刷新页面一次 response.setHeader("refresh","1"); 二秒跳到其他页面 response.setHeader("re ...