2009-06-23 8 views
7

En Scala, si j'ai une simple classe comme suit:Les propriétés de mes acteurs Scala doivent-elles être marquées @volatile?

val calc = actor { 
    var sum = 0 
    loop { 
    react { 
     case Add(n) => 
     sum += n 
     case RequestSum => 
     sender ! sum 
    } 
    } 
} 

Si mon champ sum être marqué @volatile? Alors que l'acteur est logiquement monothread (c'est-à-dire que les messages sont traités séquentiellement), les réactions individuelles peuvent se produire sur des threads séparés et donc la variable state peut être modifiée sur un thread puis lue depuis un autre thread.

Répondre

6

Vous n'avez pas besoin de les marquer comme volatiles. L'exécution de votre code ne fait pas partie d'un bloc synchronisé, mais l'acteur en passera toujours un avant que votre code ne soit invoqué, forçant ainsi la mémoire dans un état cohérent à travers les threads.

+0

Est-ce que ce n'est pas un départ significatif d'Erlang alors? Cela signifie que les acteurs ne sont pas complètement évolutifs en ce qui concerne l'ajout de cœurs - à moins qu'ils ne soient complètement apatrides. –

+0

Et la structure des acteurs ne pouvait-elle pas utiliser l'utilitaire util.concurrent.Exchanger pour transmettre l'état entre les threads? –

+1

Si une valeur actuelle de quelque chose est seulement dans un registre d'une CPU, et qu'une valeur périmée est dans un cache partagé ou dans la RAM, alors il est tout à fait possible pour une autre CPU de voir cette valeur périmée. @volatile dit à la JVM que lorsqu'une valeur est mise à jour à un endroit, cette mise à jour doit se propager avant qu'un autre thread ne tente d'accéder à cette valeur (ok, je simplifie ici ...). De même, synchronized déclenche la JVM pour s'assurer que tous les différents niveaux de mémoire sont dans un état cohérent. C'est un problème universel lorsqu'il s'agit de multicœur. –

Questions connexes