论坛首页 Java企业应用论坛

[JMM] 变量Reordering的含义

浏览 1692 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (8) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-08-05   最后修改:2009-08-05
本文的思想来源于:
Jeremy Manson and Brian Goetz, 《JSR 133 (Java Memory Model) FAQ》, February 2004, http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization

(1) 在一些情况下,对程序变量(对象实例变量、静态变量、数组元素)进行access的时候,会发现
access的执行顺序与程序中所指定的顺序并不一致。只要不改变程序的语义,编译器为了进行程
序的优化可以自由地reorder指令(instructions)。在运行期,处理器也可能以不同的顺序去执
行指令:数据可能会以不同于程序中所指定的顺序在处理器寄存器、处理器缓存以及住内存之间
移动。

(2) 下面举例说明:

  Class Reordering {
		  int x = 0, y = 0;
		  public void writer() {
		    x = 1;
		    y = 2;
		  }
		
		  public void reader() {
		    int r1 = y;
		    int r2 = x;
		  }
		}		


假设有两个线程分别执行上面的示例程序代码中的writer和reader方法。在writer方法的程序中,
x被指定在y之前进行赋值。但是由于对y的赋值并不依赖于x的值,因此编译器可以reorder这些操
作。另外,执行writer线程的处理器也完全可以先将cache中y的值写回内存,然后再将x的值写回内存。
在两个操作的中间(y的值已经被写回内存,但是x的值尚未被写回内存的时候),执行reader方法
的线程得到的结果便是 r1 = y的真实值,但是 r2 = 0,而非x的真实值。

(3) 可能进行reorder的地方包括:编译器、JIT JVM、处理器缓存。

(4) Reorder的影响。在单线程的情况下,程序不必去关注指令的真实执行顺序,同时也不必在意
reordering的影响。然而,在多线程的情况下,如果程序没有被正确地synchronized,一个线程便
能够观测到reordering对其他线程的影响,即该线程可能会透明地看到其他线程的变量acess过程与
程序中specified不同。
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics