Java 内存模型[部分概念,详细查阅书籍]

1、什么是内存模型,为什么需要它

假设一个线程为变量aVariable赋值:

aVariable = 3;

内存模型需要解决这个问题:在什么条件下,读取aVariable的线程将看到这个值为3?这似乎看起来愚蠢的问题,如果缺少同步,那么将会有很多因素使得线程无法立即甚至永远,看到另一个线程的操作结果。在编译器中生成的指令顺序,可以与源代码中的顺序不同,此外编译器还能把变量保存在寄存器而不是内存中;处理器可以乱序或者并行等方式执行指令;缓存可能改变将写入变量提交到主内存的次序;而且,保存在处理器本地缓存中的值,对于其他处理器是不可见的。这些因素都会使得一个线程无法看到变量的最新值,并且会导致其他线程中的内存操作似乎在乱序执行 - 如果没有使用正确的同步。

在单线程的环境中,我们无法看到所有这些底层技术,它们除了提高程序的执行速度外,不会产生其他影响。Java语言规范要求JVM在线程中维护一种类似串行的语义:只要程序的最终结果与在严格串行环境中执行的结果相同,那么上述所有操作都是允许的。随着处理变得越来越强大,编译器也在不断的改进:通过对指令重新排序来实现优化执行,以及使用成熟的全局寄存器分配算法。

2、平台内存模型

在共享内存的多处理器体系架构中,每个处理器都拥有自己的缓存,并且定期地与主内存进行协调。在不同的处理器架构中提供了不同级别的缓存一致性,其中一部分只提供最小的保证。即允许不同的处理器在任意时刻从同一存储位置上看到不同的值。操作系统、编译器及运行时需要弥合这种在硬件能力与线程安全需求之间的差异。

为了使Java开发人员无需关心不同架构上内存模型之间的差异,Java还提供了自己的内存模型,并且JVM通过在适当的位置上插入内存栅栏来屏蔽在Java内存模型与底层平台内存模型之间的差异。幸运的是,Java程序不需要指定内存栅栏的位置,而只需要通过正确地使用同步来找出何时将访问共享状态。

3、重排序

在没有充分同步的程序中,如果调度器采用不恰当的方式来交替执行不同线程的操作,那么将导致不正确的结果。更糟的是,JMM(Java内存模型)还使得不同线程看到的操作执行顺序是不同的,从而导致在缺乏同步的情况下,要推断操作的执行顺序将变得复杂。各种使操作延迟或者看似乱序执行的不同原因,都可以归为重排序。

同步将限制编译器、运行时和硬件对内存操作重排序的方式,从而在实施重排序时不会破坏JMM提供的可见性保证。【在大多数主流的处理器架构中,内存模型都非常强大,使得读volatile变量的性能与读取非volatile变量的性能大致相当】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值