Java线程 - 内存一致性错误

时间:2010-05-03 16:07:49

标签: java multithreading shared-memory

我正在阅读Sun's tutorial on Concurrency

但我无法准确理解内存一致性错误是什么?我搜索了一下,但没有找到任何有用的教程或文章。

我知道这个问题是主观的,所以你可以给我链接到上述主题的文章。

如果你用一个简单的例子解释它会很棒。

5 个答案:

答案 0 :(得分:7)

您可以阅读Read After Write (RAW), Write after Write(WAW) and Write After Read (WAR) hazards以了解有关此主题的更多信息。这些危险指的是流水线过程,但实际上与多线程相同。它基本上意味着两个不同的线程正在更新内存中的相同位置,如果您按特定顺序依赖这些更新,那么您可能会惊讶地发现您无法保证更新发生的顺序。

例如,如果您有两个陈述:

  x = y + z;
  r = x + z;

在单个线程中,您没有问题,因为r的值始终是一致的。然而,在多线程中,可能或者任何一个语句首先发生,而r的值更难预测。

答案 1 :(得分:4)

基本上,在没有任何同步线程的情况下,可以看到简单字段的不同值。考虑这个例子:

class Foo
{
  int bar = 0;

  void unsafeCall ( )
  {
    final Foo thisObj = this;

    Runnable r = new Runnable ( )
    {
      public void run ( )
      {
        thisObj.bar = 1;
      }
    }

     Thread t = new Thread(r);

     t.start( );
     Thread.sleep( 1000 );

     // May print bar = 0
     System.out.println( "bar = " + bar );
  }
}

避免内存一致性错误的最简单方法是将bar字段声明为volatile(有关详细信息,请参阅此处:https://www.ibm.com/developerworks/java/library/j-jtp06197/)。

强制线程重新检查内存称为内存屏障内存屏障的另一个示例是synchronized方法/块。

答案 2 :(得分:3)

嗯。他们基本上是在谈论“可见性问题”和“重新排序问题”(这个术语至少在Java IMO中更常见)。我认为这个链接:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile解释了教程正在讨论的内容,使用更常见的术语(也许是太阳试图使用“更容易”的词汇或其他东西)。

答案 3 :(得分:1)

我在搜索这个问题时找到了一个很好的例子。如下:

    Accesses to main memory might not occur in the same
    order that the CPU initiated them, particularly for writes
    (which often go through hardware write buffers so the CPU
    needn't wait for them). If CPU 1 writes the Answer to
    location A and then writes the AnswerIsReady flag to B,
    CPU 2 may see the change to B before it sees the change
    to A, and thus get the WrongAnswer. Making either or both
    writes atomic doesn't help; what's needed is something
    called a "memory barrier."

通过http://www.velocityreviews.com/forums/t390825-memory-consistency-errors.html

答案 4 :(得分:0)

如果您想更深入地了解共享内存一致性模型,我将向您推荐以下教程。

http://rsim.cs.uiuc.edu/~sadve/Publications/computer96.pdf