Java内存模型FAQ(一)什么是内存模型

Java内存模型FAQ(一)什么是内存模型

在多核系统中,处理器一般有一层或者多层的缓存,这些的缓存通过加速数据访问(因为数距离处理器更近)和降低共享内存在总线上的通讯(因为本地缓存能满足许多内存操作)来题高CPU性能。缓存能够大大提升性能,但是他们也带来了许多挑战。例如,当两个CPU同时检查相同的内存地址时会发生什么?在什么想的条件下他们会看到相同的值?

在处理器层面上,内存模型定义了一个从要条件,让当前处理器可以看到其他处理器写入到内存的数据“以及”其他处理器可以看到当前处理器写入到内存的数据。
有些处理器有很强的内存模型,能够让所有的处理器在任何时候指定的内存地址上都可以看到完全相同的值。而另一些处理器则有较弱的内存模型,在这种处理器中,必须使用内存屏障(一种特殊的指令)来刷新本地处理器缓存病史本地处理器缓存无效,目的是为了当前处理器能够看到其他处理器的写操作或者让其他处理器能够看到当前处理器的写操作。这些内存屏障通常在lock和unlock操作的时候完成。内存屏障在高级语言中对程序元是不可见的。

在强内存模型下,有时候编写程序会更容易,因为减少了对内存屏障的依赖。但是即使在一些最强的内存模型下,内存屏障仍然是必须的。设置内存屏障往往与我们的直觉并不一致。进来处理器设计的趋势更倾向于若的内存模型,因为弱内存模型削弱缓存的一致性,所以在多处理器平台和更大容量的内存下可以实现更好地可伸缩性。

“一个线程的写操作对其他线程可见”这个问题是因为编译器对代码重排序导致的。例如,只要代码移动不会改变程序的语以,当编译器认为程序移动一个写操作到后面会更有效的时候,编译器就会对代码进行移动。如果编译器推迟执行一个操作,其他线程可能在这个操作执行完之前都不会看到这个操作的结果,这反映了缓存的影响。

此外,写入内存的操作能够被移动到程序里更前的时候。在这种情况下,其他的线程在程序中可能看到一个比它实际发生更早的写操作。所有的这些灵活性的设计是为了通过给编译器,运行时或硬件灵活性使其能在最佳顺序的情况下来执行操作。在内存模型的限定之内,我们能够获取到更高的性能。

看下面代码展示的一个简单例子:ClassReordering
{
int x= 0,y=0;
public void writer(){
x=1;
y=1;

}

public void reader(){
int r1=y;
int r2=x;
}

}

让我们看在两个并发线程中执行这段代码,读取Y变量将会得到2这个值。因为这个写入比写到X变量更晚一些,程序员可能认为读取X变量将肯定会得到1。但是,写入操作可能被重排序过。如果重排序发生了,那么,就能发生对Y变量的写入操作,读取两个变量的操作紧随其后,而且写入到X这个操作能发生。程序的结果可能是r1变量的值是2,但是r2变量的值为0。

Java内存模型描述了在多线程代码中哪些行为是合法的,以及线程如何通过内存进行交互。它描述了“程序中的变量“ 和 ”从内存或者寄存器获取或存储它们的底层细节”之间的关系。Java内存模型通过使用各种各样的硬件和编译器的优化来正确实现以上事情。

Java包含了几个语言级别的关键字,包括:volatile, final以及synchronized,目的是为了帮助程序员向编译器描述一个程序的并发需求。Java内存模型定义了volatile和synchronized的行为,更重要的是保证了同步的java程序在所有的处理器架构下面都能正确的运行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值