akka如何启动主任务并阻止其完成?

问题描述:

我想在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

正如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