2010-05-03 15 views
11

Ich las eine Sun's tutorial on Concurrency.Java Thread - Speicherkonsistenz Fehler

Aber ich konnte nicht genau verstehen, was Speicher Konsistenz Fehler sind? Ich habe darüber gegoogelt, aber kein hilfreiches Tutorial oder Artikel darüber gefunden.

Ich weiß, dass diese Frage eine subjektive ist, so dass Sie mir Links zu Artikeln zum obigen Thema bereitstellen können.

Es wäre toll, wenn Sie es mit einem einfachen Beispiel erklären.

Antwort

8

Sie können über Read After Write (RAW), Write after Write(WAW) and Write After Read (WAR) hazards nachlesen, um mehr über dieses Thema zu erfahren. Diese Gefahren beziehen sich auf Pipeline-Prozesse, aber es ist wirklich das gleiche Problem, das bei Multi-Threading auftritt. Es bedeutet im Grunde, dass zwei verschiedene Threads den gleichen Speicherort im Speicher aktualisieren, und wenn Sie von diesen Updates in einer bestimmten Reihenfolge abhängig sind, werden Sie möglicherweise überrascht sein, dass Sie die Reihenfolge, in der die Updates auftreten, nicht garantieren können.

Zum Beispiel, wenn Sie zwei Aussagen haben:

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

in einem einzigen Thread, dann haben Sie kein Problem, da der Wert von r immer konsistent sein wird. In mehreren Threads ist es jedoch möglich, dass eine der Anweisungen zuerst auftritt und der Wert von r schwerer vorhersagbar ist.

2

Hm. Sie sprechen im Grunde von "Sichtbarkeitsproblemen" und "Neuordnungsproblemen" (diese Terminologie ist zumindest in Java IMO häufiger). Ich denke, dass dieser Link: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile erklärt, worüber das Tutorial spricht, unter Verwendung gebräuchlicherer Begriffe (vielleicht versuchte Sonne "einfacheren" Wortschatz oder etwas zu verwenden).

+0

+1 für den Link –

3

Grundsätzlich in Abwesenheit von Synchronisierungs-Threads kann einen anderen Wert eines einfachen Feld sehen. Betrachten Sie folgendes Beispiel:

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

Der einfachste Weg, Speicherkonsistenzfehler zu vermeiden, ist bar Feld zu erklären volatile zu sein.

Diese Erzwingung von Threads zum erneuten Überprüfen des Speichers heißt Speicherbarriere. Ein anderes Beispiel für Speicherbarriere ist eine synchronized Methode/Block.

1

finde ich ein gutes Beispiel, wenn diese Frage zu suchen. Wie weiter unten:

 
    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." 

über http://www.velocityreviews.com/forums/t390825-memory-consistency-errors.html