Java Thread - ошибки согласованности памяти

Я читал учебник Sun по Concurrency.

Но я не мог точно понять, что такое ошибки согласованности памяти? Я искал эту информацию, но не нашел полезного учебника или статьи об этом.

Я знаю, что этот вопрос является субъективным, поэтому вы можете предоставить мне ссылки на статьи по вышеуказанной теме.

Было бы здорово, если бы вы объяснили это простым примером.

Ответ 1

Вы можете прочитать Read After Write (RAW), Write after Write (WAW) и Write After Read (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( );

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

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

Самый простой способ избежать ошибки согласованности памяти - объявить поле bar равным volatile.

Это форсирование потоков, чтобы перепроверять память, называется барьером памяти. Еще один пример барьера памяти - это метод/блок synchronized.

Ответ 3

Hm. В основном они говорят о "проблемах видимости" и "проблемах переупорядочения" (эта терминология чаще встречается, по крайней мере, в Java IMO). Я думаю, что эта ссылка: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile объясняет, о чем говорится в учебнике, используя более распространенные термины (возможно, солнце пыталось использовать "более легкий" словарь или что-то).

Ответ 4

Я нахожу хороший пример при поиске этого вопроса. Как ниже:

    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 needed is something
    called a "memory barrier."

через http://www.velocityreviews.com/forums/t390825-memory-consistency-errors.html

Ответ 5

Если вы хотите получить более глубокое представление о моделях согласованности с общей памятью, я приведу вам следующий учебник.

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