2011-05-01 26 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