2010-05-03 6 views
11

Je lisais un Sun's tutorial on Concurrency.Fil Java - Erreurs de cohérence de la mémoire

Mais je ne pouvais pas comprendre exactement ce que erreurs de cohérence de la mémoire sont? J'ai fait des recherches sur Google à ce sujet, mais je n'ai trouvé aucun didacticiel ou article utile à ce sujet. Je sais que cette question est subjective, vous pouvez donc me fournir des liens vers des articles sur le sujet ci-dessus.

Ce serait bien si vous l'expliquez avec un exemple simple.

Répondre

8

Vous pouvez en savoir plus sur Read After Write (RAW), Write after Write(WAW) and Write After Read (WAR) hazards pour en savoir plus sur ce sujet. Ces dangers se réfèrent à des processus pipelined mais c'est vraiment le même problème qui se produit avec multi threading. Cela signifie essentiellement que deux threads différents mettent à jour le même emplacement en mémoire et si vous dépendez de ces mises à jour dans un certain ordre, vous serez peut-être surpris de constater que vous ne pouvez pas garantir l'ordre dans lequel les mises à jour se produisent.

Par exemple, si vous avez deux déclarations:

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

dans un seul thread alors vous avez pas de problème parce que la valeur de r sera toujours cohérente. Cependant, dans plusieurs threads, il est possible que l'une des deux instructions apparaisse en premier et que la valeur de r soit plus difficile à prévoir.

2

Hm. Ils parlent essentiellement de «problèmes de visibilité» et de «réordonnancement des problèmes» (cette terminologie est plus courante au moins dans Java IMO). Je pense que ce lien: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile explique ce que le tutoriel parle, en utilisant des termes plus communs (peut-être que le soleil a essayé d'utiliser un vocabulaire "plus facile" ou quelque chose comme ça).

+0

+1 pour le lien –

3

Fondamentalement, en l'absence de synchronisation threads peut voir une valeur différente d'un champ simple. Considérez cet exemple:

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

La façon la plus simple d'éviter une erreur de cohérence de la mémoire est de déclarer le terrain bar être volatile.

Ce forçage de threads pour revérifier la mémoire est appelé barrière de mémoire. Un autre exemple de barrière de mémoire est une méthode/bloc synchronized.

1

je trouve un bon exemple lors de la recherche à cette question. Comme ci-dessous:

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

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