Java 内存模型

Java的内存模型分为主存储器和工作存储器两种。 主存就是实例位置所在的区域。主存为全部线程锁共用;每一个线程都拥有自己独立的作业区,称为工作存储器。 当一个线程须要对某对象的一些字段进行操作时,就会把这些须要的信息从主存储器copy到自己的工作存储器。而这个拷贝就叫做工作拷贝。

讲到这里大家都能够想象Java是怎样保证内存一致的了。主存上面的内容就像是个标准,而每一个线程的工作拷贝就像是草稿。草稿上计算好的结果就要放到主存去。这样其它线程也能够看得到,这就是可见性了。当一个线程获得某一对象的锁,他就获得了改动这个对象状态的权利,他開始copy主存的内容到他的工作存储器。这个时候他对工作拷贝的不论什么改动都没有在主存上,而当他要释放锁的时候就必须把工作拷贝写入到主存去。为什么呢?他假设不写的话主存上的内容还是曾经的内容,仅仅只是其它线程不知道有个线程做了一些事情,能够忽略啊。问题就是不能忽略,为了保证每一个线程做的事情都被他后面的线程看到,他必须在释放锁之前就把内容写到主存,即使他自己的工作仅仅完毕了部分。

这样才有先获得锁和后获得锁的差别,先获得锁的线程所做的操作对后获得锁的线程是可见的。

当然线程不是仅仅有在释放锁时才会被工作拷贝写入主存。他能够在对对象的字段进行一次指定之后就进行一次写入,也能够到最后将终于值写入。由处理器决定。

方法的自变量和局部变量为每一个线程所独有,所以不用考虑同步。

多线程编程须要解决的两个问题就是线程间的干扰和内存不一致问题,synchronized在这里是恰到优点的,它的两个作用就是“线程的同步”和”内存的同步“。 synchronized所保护的方法或者块被称作临界区,在同一时刻仅仅有一个线程能够訪问,就像独木桥。并且是仅仅有一个人能够上去的独木桥。

内存的同步指的就是主存储器和工作存储器上的内容的同步,要保证两个内容是一样的。

那什么时候去进行同步呢。不可能时时刻刻都去同步吧,那全部线程都在一直看自己有没有跟主存同步。这样不是浪费时间吗?线程会在“欲进入synchronized块”和“欲退出synchronized块”是进行同步,同步包含双方面,一个是把自己的工作拷贝写到主存。一个是从主存读内容。在线程欲进入synchronized时会将工作拷贝中没有写入到主存的内容强制写入主存,在退出synchronized是会做相同的强制写入。

不同的是在进入synchronized时线程还会释放工作存储器。这样能够保证新的内容的读入,可是在欲退出synchronized时则不会释放工作存储器,毕竟这个时候还不用考虑读入新的内容,总之下次进入synchronized块时一定会读的。

由此可见主存和工作存储器上的内容并非总是同步的,并且大多数时候应该是不一样的。内存的同步就是保证须要用到这个内容的时候和主存是一致的。对它做完改动之后保证把内容写入主存。

换句话说保证别人写的你看到了,保证你写的别人也看到了。

volatile的与synchronized不同的是它仅仅会进行内存的同步,并不能保证线程的同步。

当线程引用valotile字段时,会先从主存copy值到工作存储器,当线程指定值到volatile字段时会copy值到主存。

volatile的还有一个功能是保证对long和double的指定动作的原子性。指定一个int或者bye之类的基本数据类型都是原子的,仅仅有指定long和double须要分成两次,这就可能导致在多线程的时候出现脏数据。所以在多线程编程中一定要保证对long和double的原子訪问。

时间: 2024-12-17 17:28:59

Java 内存模型的相关文章

深入理解Java内存模型(四)——volatile

volatile的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别.理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步.下面我们通过具体的示例来说明,请看下面的示例代码: class VolatileFeaturesExample { //使用volatile声明64位的long型变量 volatile long vl = 0L; public void set(long l) { vl = l;

深入理解Java内存模型(1 ) -- 基础(转载)

原文地址:http://www.infoq.com/cn/articles/java-memory-model-1 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.在消息传递的并发模型里,线程之间没有公共状态,线

对java内存模型的认识

浅谈java内存模型        不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的.其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改.总结java的内存模型,要解决两个主要的问题:可见性和有序性.我们都知道计算机有高速缓存的存在,处理器并不是每次处理数据都是取内存的.JVM定义了自己的内存模型,屏蔽了底层平台内存管理细节,对于java开发人员,要清楚在jvm内存模型的基础上,如果解决多线程的可见性和有序性

(第三章)Java内存模型(中)

一.volatile的内存语义 1.1 volatile的特性 理解volatile特性的一个好办法是把对volatile变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步.下面通过具体的示例来说明,示例代码如下: class VolatileFeaturesExample { volatile Long vl = 0L; //使用volatile声明64位的Long型变量 public void set(Long l) { vl = l; //单个volatile变量的写 } p

java内存模型-volatile

volatile 的特性 当我们声明共享变量为 volatile 后,对这个变量的读/写将会很特别.理解 volatile 特性的一个好方法是:把对 volatile 变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步.下面我们通过具体的示例来说明,请看下面的示例代码: class VolatileFeaturesExample { //使用volatile声明64位的long型变量 volatile long vl = 0L; public void set(long l) {

java内存模型与线程(转) good

java内存模型与线程 参考 http://baike.baidu.com/view/8657411.htm http://developer.51cto.com/art/201309/410971_all.htm http://www.cnblogs.com/skywang12345/p/3447546.html 计算机的CPU计算能力超强,其计算速度与 内存等存储 和通讯子系统的速度相比快了几个数量级, 数据加载到内存中后,cpu处理器运算处理时,大部分时间花在等待获取去获取磁盘IO.网络通

Java内存模型与垃圾回收

1.Java内存模型 Java虚拟机在执行程序时把它管理的内存分为若干数据区域,这些数据区域分布情况如下图所示: 程序计数器:一块较小内存区域,指向当前所执行的字节码.如果线程正在执行一个Java方法,这个计数器记录正在执行的虚拟机字节码指令的地址,如果执行的是Native方法,这个计算器值为空. Java虚拟机栈:线程私有的,其生命周期和线程一致,每个方法执行时都会创建一个栈帧用于存储局部变量表.操作数栈.动态链接.方法出口等信息. 本地方法栈:与虚拟机栈功能类似,只不过虚拟机栈为虚拟机执行J

深入理解Java内存模型-volatile

volatile的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别.理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用同一个监视器锁对这些单个读/写操作做了同步.下面我们通过具体的示例来说明,请看下面的示例代码: class VolatileFeaturesExample { volatile long vl = 0L; //使用volatile声明64位的long型变量 public void set(long l) { vl =

深入java内存模型(一)

最近本来想深入学习一下java线程,很想知道其中实现的原理,比如线程资源的共享,线程私有空间,以及线程直接的同步控制等.如果能了解它的实现,对于深入学习线程,会有很大的帮助.最近正在看一份<深入java内存模型>的资料.讲的就是java线程方面的实现原理,拿出来分享一下. 说到线程,我们首先想到的是线程的通信.学习操作系统时,线程通信有两种,一种是通过共享内存,另一种是通过消息传递.共享内存属于隐式的通信,线程之间共享一块内存,线程都可以往这块内存写数据,读数据就实现了通信.而消息传递时一个显

深入理解Java内存模型之系列篇[转]

原文链接:http://blog.csdn.net/ccit0519/article/details/11241403 深入理解Java内存模型(一)——基础 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. see:命令式编程.函数式编程 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存