2011-05-16 69 views
3

我想在scala中開始使用akka。在主要的Scala線程中,我想創建一個AKK演員,向它發送一條消息,並阻止該演員終止。做這個的最好方式是什麼?akka如何啓動主任務並阻止其完成?

例如我有一個測試演員,只是重複發送消息到其自身:

class Incrementer() extends Actor { 

    val maxMessages = 5 
    var counter = 0 

    def receive() = { 
    case DoIncr() => { 
     if (counter < maxMessages) { 
     counter += 1 
     self ! DoIncr() 
     } else { 
     self.stop() 
     } 
    } 
    } 
} 

並且它經由調用:剛剛超過5000毫秒來執行,而不是

val inc = actorOf(new Incrementer()).start() 
val result = inc !! DoIncr() 
println(result) // this should block this thread, but it doesn't seem to. 

// do other stuff 

即塊取我希望是幾ms,所以它似乎與默認的未來超時有關 - 並且程序實際上並未終止。我真正想要做的就是發送x條消息的時間。這裏發生了什麼?

+0

您沒有回覆任何第一條DoIncr郵件(您發送的是「inc !! DoIncr」。 – 2011-05-16 07:17:49

+0

謝謝 - 如果您有一連串的郵件,顯然該鏈中的第一個演員無法回覆主線程解鎖它,直到鏈中的最後一個actor被處理完爲止,在akka中做到這一點的最好的習慣方法是什麼?最好是鏈中的最後一個actor能夠以某種方式發信號通知主線程,而不是傳遞所有的信息鏈接到第一個參與者 – user747980 2011-05-16 07:42:55

+0

爲什麼你想阻止主線程? – 2011-05-16 09:05:36

回答

4

正如Viktor提到的,爲了使!!成功終止,您必須回覆郵件。 5秒延遲你看到了演員的默認超時,這是可配置的。更多信息可以在Akka site找到。

如果您使用forward發送消息而不是!,則self.reply將響應原始發件人。

發送給Akka actor的第一條消息會執行一些在處理其他消息時不會發生的設置。一定要考慮到你的時間。

更正後的代碼將是:

import akka.actor._ 

object DoIncr 

class Incrementer extends Actor { 
    val maxMessages = 5 
    var counter = 0 

    def receive = { 
    case DoIncr => 
     if (counter < maxMessages) { 
     counter += 1 
     self forward DoIncr 
     } else { 
     self.reply(()) // replying with() since we have nothing better to say 
     self.stop() 
     } 
    } 
} 

除了:我做了一些其他的變化與慣用的Scala得到一致的代碼。你的代碼沒有這些變化,但現在看起來像更典型的Scala代碼。

  • 不包含參數列表的案例類已被棄用。改爲使用object
  • 如果你有一個沒有參數列表的類,你可以省略括號
  • Actorreceive方法沒有parens;你的實施班也不應該有他們。
  • 這完全是一個風格問題,但case聲明的正文不需要大括號。
+0

對不起,也許愚蠢的問題:我如何導入/我在哪裏可以找到關於'!!'的更多信息?我搜索了一下,但沒有找到太多.. – xysun 2015-02-07 14:28:40

相關問題