2011-05-01 24 views
4

我想这个代码可以在scala中启动多少个演员?

import scala.actors.Actor 

class MyActor(val id:Int) extends Actor { 
    def act() { 
     println (" ****************** starting actor: " + id) 

     while (true) { 
      Thread.sleep(1000); 
      println ("I'm actor " + id) 
     } 
    } 
} 

object Main { 
    def main(args:Array[String]) { 
     val N = 5 
     for (i leftArrow 1 to N) { 
      val a = new MyActor(i) 
      println (" ++++++++++ about to start actor " + a.id) 
      a.start 
     } 

     println (N + " actors launched?") 
    } 
} 

,并得到了这个输出

++++++++++ about to start actor 1 
++++++++++ about to start actor 2 
++++++++++ about to start actor 3 
++++++++++ about to start actor 4 
++++++++++ about to start actor 5 
5 actors launched? 
****************** starting actor: 1 
****************** starting actor: 4 
****************** starting actor: 3 
****************** starting actor: 2 
I'm actor 4 
I'm actor 3 
I'm actor 1 
I'm actor 2 
I'm actor 4 

那么,是什么我失踪,只有四个演员实际上正在启动? 它取决于我的电脑吗?一些配置?我应该以不同的方式启动 演员吗?是因为我在netbeans里面运行这个代码吗?

非常感谢!

+0

一旦你的问题得到解答,*不要*编辑问题以反映答案。只需接受答案,并按照以下方式评论任何实际上不在答案中的信息。 – 2011-05-03 02:26:19

回答

8

我认为这与scala的演员池有关。它可能(我仍然在等待着我的书“斯卡拉的演员”)创建了一个包含四个线程(可能与您的四核CPU相关)的池,并将您的演员分配给他们。问题是,你使用Thread.sleep。这吸引了某个线程并绕过scala的actor来进行线程分配。

+1

你说得对。我用 receiveWithin(1000)替换了Thread.sleep(1000){case _ => None},它现在可以工作了! – cibercitizen1 2011-05-01 16:47:57

6

Scala中基本上有两种角色(当使用标准Scala 2.8角色时):基于线程和基于事件的角色。

当您使用receive(或​​),如在您的示例中,您正在创建基于线程的演员,这是相对重量级的。每个演员都有一个单独的线程,只要演员正在等待消息,该线程就会被阻止。

当您使用react而不是receive时,您的演员将成为基于事件的演员。基于事件的角色更轻量化;基于事件的参与者和线程之间不存在一对一的关联。您可以轻松创建数千个基于事件的演员。

我写了一个blog post(和示例应用程序)的更多细节。

+0

如果你既没有反应也没有接受,那么它是什么类型的演员?它没有收到任何消息。 – Jus12 2011-05-03 12:06:58

+0

@ Jus12在这种情况下,actor系统会运行所有的actor,并使用线程池机制来调度它们。只要演员正在运行,他们每个都会占用一个线程,所以在这方面他们会像基于线程的演员一样。基于事件的参与者的观点是,他们在等待消息时不会阻止每个参与者的线程(与基于线程的参与者不同)。 – Jesper 2011-05-03 12:25:13