2009-09-04 5 views
2

J'ai le code suivant. Si je commente l'appel à "foo()" dans le corps de l'acteur, le code fonctionne bien. Mais si "foo()" est activé ... mon code se fige!L'appel de méthode à l'intérieur de l'acteur se bloque dans Scala

Quelqu'un sait pourquoi?

import scala.actors.Actor._ 

object Main extends Application{ 
    def foo() = { 
     println("I'm on foo") 
    } 

    def testActor() = { 
     val target = self 

     for(i <- 1 to 100){ 
      actor{ 
       foo() 
       target ! i 
      } 
     } 

     var total = 0 
     receive{ 
      case x:Int => total += x 
     } 
     total 
    } 

    println("Result: " + testActor()) 
} 

Répondre

2

Le code de l'acteur s'exécute dans un thread différent (pas le thread principal) et il est bloqué et ne peut envoyer aucun message car il tente d'accéder à une méthode dans une classe (Main dans ce cas) en cours d'initialisation dans le thread principal. "recevoir" se bloque car il ne peut recevoir aucun message.

N'utilisez pas "étend l'application". Utilisez "def main (args: Array [String])" et économisez beaucoup d'ennuis.

Voir http://scala-blogs.org/2008/07/application-trait-considered-harmful.html

2

Le caractère Application et son utilisation sont en cause ici. Lorsque vous exécutez du code dans le corps d'un Application plutôt que dans une méthode main, ce code est en cours d'exécution dans le cadre du constructeur. Ainsi, au moment où vous appelez la méthode testActor(), l'initialisation de l'objet n'a pas réellement été terminée.

Pour résoudre ce problème, déplacer la ligne println dans une méthode principale:

def main (args: Array[String]) { 
    println("Result: " + testActor()) 
} 

Parce que ce problème se produit si facilement, le trait Application est considéré comme de mauvaises nouvelles. "TestActor" est appelé pendant l'initialisation de la classe "Main".

+0

Comme mentionné ici: http://stackoverflow.com/questions/1332574/common-programming-mistakes-for-scala-developers-to-avoid/1334962#1334962 –

Questions connexes