Java千百问_07JVM架构(001)_java内存模型是什么样的

1、什么是内存模型

  Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉害很多。Java针对多种异构平台的独立性,使得多线程技术也具有了开拓性的一面。 
我们有时候在Java开发中,对于同步和线程安全要求很严格的程序时,往往容易混淆的一个概念就是内存模型。那究竟什么是内存模型呢? 
内存模型描述了程序中各个变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存、从内存中取出变量这样的底层细节。 
Java对象最终是存储在内存里面的,这点没错,但是编译器、运行库、处理器或者系统缓存有权指定内存位置来存储或者取出变量的值。

2、内存模型有哪些规则

内存模型需要具有以下规则:原子性(Atomicity)、可见性(Visibility)、可排序性(Ordering) 
1. 原子性(Atomicity) 
原子性指的是原子级别的操作,比如最小的一块内存的读写操作,可以理解为Java语言编译过后最接近内存的最底层的操作单元。这种读写操作的数据单元不是变量的值,而是本机码。

原子性规则约定了:访问存储单元内任何类型字段的值以及对其更新操作时,除了long类型和double类型,其他类型的字段是必须要保证其原子性的,这些字段也包括为对象服务的引用。即,如果你获得或者初始化某一些值时(这些值是由其他线程写入的,而且不是从两个或者多个线程在同一时间戳混合写入的),该值的原子性在JVM内部是必须得到保证的。

此外,原子性扩展规则可以延伸到基于long和double的另外两种类型:volatile long和volatile double(volatile为java关键字),没有被volatile声明的long类型以及double类型的字段值虽然不保证其JMM中的原子性,但是是被允许的。

只要在不违反该规则的情况下,JVM并不关心数据的值来自什么线程,正这样使得Java语言在并行运算的设计中,针对多线程的原子性设计变得极其简单。即使开发人员没有考虑到,最终的程序也没有太大的影响。

2. 可见性(Visibility) 
可见性指的是一个线程修改的状态对另一个线程是可见的。也就是说一个线程修改的结果,另一个线程马上就能看到。比如:用volatile修饰的变量,就会具有可见性。volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存,所以对其他线程是可见的。但是这里需要注意一个问题,volatile只能让被他修饰内容具有可见性,但不能保证它具有原子性。比如 volatile int a = 0;之后有一个操作a++;这个变量a具有可见性,但是a++依然是一个非原子操作,也就这这个操作同样存在线程安全问题。

在可见性规则的约束下,定义了一个线程在哪种情况下可以访问或者影响另外一个线程,以及从另外一个线程的可见区域读取相关数据、将数据写入到另外一个线程内。

3. 可排序性(Ordering) 
可排序性是指为了提高性能,编译器和处理器可能会对指令做重排序,包括:

  • 编译器优化的重排序 
    编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。
  • 指令级并行的重排序 
    现代处理器采用了指令级并行技术(Instruction-LevelParallelism,ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
  • 内存系统的重排序 
    由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。

volatile修饰的变量不允许线程内部缓存和重排序。 
可排序性规则将会约束任何一个违背了规则调用的线程在操作过程中的一些顺序,排序问题主要围绕了读取、写入和赋值语句有关的序列。

3、Java内存模型是什么

JMM(Java内存模型,Java Memory Model的缩写)是控制Java线程之间、线程和主存之间通信的协议。 
JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。 
JMM结构如下: 

原文地址:http://blog.csdn.net/ooppookid/article/details/51418312

时间: 2024-09-17 04:09:40

Java千百问_07JVM架构(001)_java内存模型是什么样的的相关文章

Java千百问_05面向对象(003)_java中抽象概念如何体现的

点击进入_更多_Java千百问 1.抽象是什么 抽象,和具体对立,定义了事物的性质,事物的性质会随着抽象概念的改变而改变. 2.java中的抽象类是什么 Java中最直接抽象概念的应用就是抽象类和接口,这里我们看一下抽象类. 抽象类和普通类一样,是一个模版.相比普通类,抽象类不具备实例化对象的能力.抽象类也可以定义属性和方法,比之普通类,它还可以定义没有实现的方法,即抽象方法.  通常会用一个具体类(子类)继承抽象类(父类),实现抽象类中的抽象方法.父类包含子类的集合的通用功能,但父类本身过于抽

Java千百问_03基本语法(002)_java都有哪些关键字

java都有哪些关键字 首先我们来看看什么是关键字,关键字的含义. 1.java关键字是什么意思 关键字是电脑语言里事先定义的,有特别意义的特殊标识符,又叫保留字. Java的关键字对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等等,Java规定关键字不能用作自定义标识符(包括变量名.方法名.类名.包名和参数等等). 2.java都有哪些关键字 目前共有50个Java关键字,如下.其中,"const"和"goto"这两个关键字在Java

[置顶] Java千百问_06数据结构(001)_java中数据类型是什么

1.什么是数据类型 Java语言是静态类型的(statical typed),也就是说所有变量和表达式的类型再编译时就已经完全确定.由于是statical typed,导致Java语言也是强类型(Strong typed)的.  强类型意味着每个变量都具有一种类型,并且每种类型都是严格定义的(当然泛型比较特殊,看这里:泛型是什么),类型限制了变量可以赋哪些值,表达式最终产生什么值.同时限制了这些值可以进行的操作类型以及具体方法.所有的赋值操作,无论是显式的还是在方法调用中通过参数传递,都要进行类

Java千百问_02基本使用(004)_java开发应该使用什么工具

java开发应该使用什么工具 如果想编写大量的Java代码,使用记事本开发费时又费力,而且非常容易出错,也不能很方便的编译运行,效率非常低(使用记事本开发:如何用记事本编写Java程序).在这种情况下,一款快捷.宜用的开发工具就非常必要了.开发Java,根据开发方向的不同,我们会选择不同的工具,最为普遍的就是免费的Eclipse.NetBeans,收费的MyEclipse.JBuilder等,这些都属于集成开发环境(即IDE),我们首先看看什么是开发领域的IDE. 1.什么是IDE IDE,即I

Java千百问_05面向对象(008)_java中覆盖是什么

1.什么是覆盖 在Java中,覆盖是针对继承才有的概念,某一个子类需要某些方法或属性,但又不想使用父类中的同名的方法或属性,就需要使用覆盖.  直白的来说,就是在子类中编写与父类同名.同参数.同返回值的方法,或同名.同类型的属性,子类对象调用该方法/属性时,运行的是子类的方法,而不会执行父类的方法(除非在方法第一行写super();会先执行父类方法,再继续执行子类代码.) 了解类的构造函数看这里:类.对象到底有什么秘密  了解更多继承看这里:java类的继承有什么意义 2.构造函数如何覆盖 了解

Java千百问_03基本语法(004)_java中的运算符都有哪些

java中的运算符都有哪些 Java提供了丰富的运算符来操纵变量.如果不知道什么是变量,看这里:局部变量.类变量.实例变量有什么区别 我们可以把所有的Java操作符为以下几组(除位运算和其它运算符之外,其他几种操作无几乎是java中使用频率最高的语法): 算术运算符.关系运算符.逻辑运算符.赋值运算符.位运算符.其它运算符 下面来仔细说明.运算符的优先级看这里:java运算符的优先级是怎样的 1.算术运算符 算术运算符用于在数学表达式中,他们是在代数中使用的方法相同.假设整型变量a=20,b=1

Java千百问_01基本概念(002)_Java都有哪些版本

Java都有那些版本 Java最初由sun公司出品,2009年被orcale公司(即甲骨文)收购,它的版本体系分为两个纬度,纵向和横向. 纵向的版本即为我们常说的Jdk版本,通过近20年的时间,从1996年正式发布1.0版本,发展到2014年的8.0版本. 横向的版本即为我们所说的Java体系,从Java 2.0开始有所区分. 1.什么是Java体系 Java SE(J2SE,Java2 Platform Standard Edition,标准版) Java EE(J2EE,Java 2 Pla

Java千百问_05面向对象(001)_类、对象到底有什么秘密

1.类.对象的概念是什么 Java是目前应用最为广泛的面向对象特的语言,它具有以下基本概念: 类 对象 方法 抽象化 多态性 继承 封装 我们首先看看类和对象的概念. 类 类是一个模版.是一个可以定义一类具有相同属性.行为的模版.  例如:狗是一个类,它具有四肢.尾巴.头.脊椎等属性,具有吠叫.吃.繁殖等行为. 对象 对象是一个具体实例.根据是一个类的具体实例.  例如:我家对门养的一只狗,具体到了某一只. 2.Java如何定义类 类的定义如下︰ public class Dog{ String

Java千百问_05面向对象(009)_java的多态性都有什么表现

1.什么是多态 多态是对象具有多种表现形式的能力.  在面向对象语言中,接口的多种不同的实现方式即为多态.  多态性的科学解释:允许你将父对象设置成为一个或更多的他子对象的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作.  通俗的解释,就是一句话:可以把一个子类的对象转换为父类的对象.  在Java中,所有的Java对象是多态的,因为任何对象都可以设置为自己本身的类和Object类(Object是所有类的父类). 了解跟多继承看这里:java类的继承有什么意义 2.如