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条消息的时间。这里发生了什么?
答
正如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
。 - 如果你有一个没有参数列表的类,你可以省略括号
-
Actor
的receive
方法没有parens;你的实施班也不应该有他们。 - 这完全是一个风格问题,但
case
声明的正文不需要大括号。
+0
对不起,也许愚蠢的问题:我如何导入/我在哪里可以找到关于'!!'的更多信息?我搜索了一下,但没有找到太多.. – xysun 2015-02-07 14:28:40
您没有回复任何第一条DoIncr邮件(您发送的是“inc !! DoIncr”。 – 2011-05-16 07:17:49
谢谢 - 如果您有一连串的邮件,显然该链中的第一个演员无法回复主线程解锁它,直到链中的最后一个actor被处理完为止,在akka中做到这一点的最好的习惯方法是什么?最好是链中的最后一个actor能够以某种方式发信号通知主线程,而不是传递所有的信息链接到第一个参与者 – user747980 2011-05-16 07:42:55
为什么你想阻止主线程? – 2011-05-16 09:05:36