日期:2014-05-16  浏览次数:20303 次

java并发学习之四:JSR 133 (Java Memory Model) FAQ【译】

?

Jsr133地址:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf

原文的地址:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html

JSR 133 (Java Memory Model) FAQ
Jeremy Manson and Brian Goetz, February 2004

1.到底什么是存储模型?

在多处理器系统,处理器通常有一个或者更多层高速缓存(像hibernate的二级缓存),通过提高访问数据的速度(因为数据更靠近处理器)和通过减少共享内存总线的使用(因为很多内存的操作可以通过本地的高速缓存来实现)提高了很大的性能。很多缓存可以极大地提高性能,然而他们面临着一个新的挑战。举个例子:当两个处理器在同一时间检查同一个内存地址时,会发生什么事?在什么条件下我们能看到相同的值?

?

在处理器的层次,一个存储模型定义必要的并且足够的条件,让当前的处理器可以看到另外的处理器写进一个储存(memory,如一个变量),并且当前的处理器的写进memory能被别的处理器看到。一些处理器展示了一个强壮(Strong)的存储模型,他可以让所有的处理器看到储存在一个memory的正确的相同的值。其他的处理器展示了一个较弱的存储模型,它提供一些特殊的指令,叫做存储屏障,这些指令可以flush或者invalidate这个本地寄存器的高速缓存,以便可以看到别的寄存器的写memory操作和让本寄存器的写memory被别的寄存器看到。当执行lock或者unlock动作的时候,这些存储屏障通常会表现出来,他们在一个高层语言是对编程人员是不可见的

有时,用强健(Strong)的存储模型写程序更加容易,因为可以减少存储屏障的试用。然而,即使是一些最强健的存储模型,存储屏障经常也是有必要的:quite frequently their placement is counterintuitive。现代的趋势是,处理器的设计上,较弱的内存模型更被支持,因为他们缓和了高速缓存的一致性问题,允许了更大的吞吐率通过多处理器和大容量内存。

这个事件:一个写操作对其他的线程变得可见,通过编译器的reordering的代码实现是很复杂的。举个例子,编译器可能认为在某个程序里面将一个写操作推迟会更有效率,只要这个代码动作不会影响程序的语义,他是被允许的。如果一个编译器推迟了一个操作,另一个线程将不会看到直到该操作发生。这也反应了缓存的一个后果。

而且,写memory在程序中可以很轻易地被移位。这样一来,在程序中其他的线程可能会看到一个写操作发生在真正的“occurs”之前。所有这些可以被灵活地设计,让编译器,runtime,或者硬件有更大的灵活性去用一个优化的顺序运行操作,在一个内存模型的限制,我们能得到更高的性能

下面的代码是一个简单的例子