Java 线程 - 内存一致性错误

2022-09-03 14:54:21

我正在阅读Sun关于并发的教程

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

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

如果你用一个简单的例子来解释它,那就太好了。


答案 1

您可以阅读有关写入后读取 (RAW)、写入后写入 (WAW) 和读取后写入 (WAR) 危害的信息,以了解有关此主题的更多信息。这些危险是指流水线进程,但实际上与多线程发生的问题相同。这基本上意味着两个不同的线程正在更新内存中的同一位置,如果您以某种顺序依赖这些更新,那么您可能会惊讶地发现您无法保证更新发生的顺序。

例如,如果您有两个语句:

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

在单个线程中,您没有问题,因为r的值将始终是一致的。然而,在多个线程中,可以或任一语句首先出现,并且更难预测r的值。


答案 2

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

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 );
  }
}

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

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