同步和Java内存模型 (二)原子性

原文:http://gee.cs.oswego.edu/dl/cpj/jmm.html 第二章

作者:Doug Lea 译者:程晓明  校对:方腾飞

除了long型字段和double型字段外,java内存模型确保访问任意类型字段所对应的内存单元都是原子的。这包括引用其它对象的引用类型的字段。此外,volatile long 和volatile double也具有原子性 。(虽然java内存模型不保证non-volatile long 和 non-volatile double的原子性,当然它们在某些场合也具有原子性。)(译注:non-volatile long在64位JVM,OS,CPU下具有原子性)

当在一个表达式中使用一个non-long或者non-double型字段时,原子性可以确保你将获得这个字段的初始值或者某个线程对这个字段写入之后的值;但不会是两个或更多线程在同一时间对这个字段写入之后产生混乱的结果值(即原子性可以确保,获取到的结果值所对应的所有bit位,全部都是由单个线程写入的)。但是,如下面(译注:指可见性章节)将要看到的,原子性不能确保你获得的是任意线程写入之后的最新值。 因此,原子性保证通常对并发程序设计的影响很小。


原文

Atomicity

Accesses and updates to the memory cells corresponding to fields of any type except long or double are guaranteed to be atomic. This includes fields serving as references to other objects. Additionally, atomicity extends to volatile long and double. (Even though non-volatile longs and doubles are not guaranteed atomic, they are of course allowed to be.)

Atomicity guarantees ensure that when a non-long/double field is used in an expression, you will obtain either its initial value or some value that was written by some thread, but not some jumble of bits resulting from two or more threads both trying to write values at the same time. However, as seen below, atomicity alone does not guarantee that you will get the value most recently written by any thread. For this reason, atomicity guarantees per se normally have little impact on concurrent program design.

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 同步和Java内存模型 (二)原子性

  • Trackback 关闭
  • 评论 (5)
    • heipacker
    • 2013/09/25 9:25下午

    不错!

    • ryvius
    • 2014/05/24 11:06下午

    public class Test {

    public static int a = 0;

    public static void r(){
    new Thread(){
    @Override
    public void run() {
    while(true){
    //long a=Test.a;
    if(a!=0&&a!=-1){
    System.out.println(a);
    }
    }

    }
    }.start();
    }

    public static void w(){
    new Thread(){
    @Override
    public void run() {
    while(true){
    a = a==-1?0:-1;
    }

    }
    }.start();
    }

    public static void main(String[] args) throws Exception {
    r();
    w();
    }

    }

    这个代码会输出内容。“除了long型字段和double型字段外,java内存模型确保访问任意类型字段所对应的内存单元都是原子的”。这句话貌似不对啊。

      • ryvius
      • 2014/05/24 11:10下午

      if(a!=0&&a!=-1) 这个改成if(a!=0||a!=-1) 上面的写错了。

    • ryvius
    • 2014/05/24 11:12下午

    啊呀,自己想错了,这里读了两次肯定读到的不一致了。。测试代码有问题。

      • 匿名
      • 2014/07/21 6:18下午

      while(true){
      //long a=Test.a;
      int b = a;
      if(b!=0&&b!=-1){
      System.out.println(b);
      }

      会不会就好了?

return top