在Java中向一个Actor发送PoisonPill

12

我开始学习Akka,通过将现有的Java SE应用程序迁移到Akka来实现。我正在使用Akka 2.0.3。

在某个时刻,我需要通过消息队列发送PoisonPill来停止演员(actors)。我的演员(actor)是这样实例化的:

ActorRef myActor = actorSystem.actorOf(new Props(MyActor.class), "myActor");

我试图发送PoisonPill到这里:

myActor.tell(PoisonPill.getInstance());

但是我得到了以下编译器错误:

'tell(java.lang.Object)' in 'akka.actor.ActorRef' cannot be applied to '(akka.actor.PoisonPill$)'

我做错了什么?我在Idea中运行Java 1.6.0_26(我之前一直使用Eclipse,现在正在学习Idea)。


编辑:

我还尝试了这种方法,这是文档中提供的,但我得到了相同的编译器错误,并且Idea警告我Actors类已过时。

import static akka.actor.Actors.*;
extractionActor.tell(poisonPill());

7
问题标题点个赞。我不知道它是关于什么的,但它读起来有点像惊悚或恐怖电影中的场景。 - Ridcully
这非常正确 - 我从未像那样阅读过它!相信我,在现实生活中,我其实是一个非常好的人。 - Rich
3个回答

9

请阅读Akka文档,我们花了很多时间创建它:

PoisonPill

You can also send an actor the akka.actor.PoisonPill message, which will stop the actor when the message is processed. PoisonPill is enqueued as ordinary messages and will be handled after messages that were already queued in the mailbox.

Use it like this:

   import static akka.actor.Actors.*;
   myActor.tell(poisonPill());

自2.0.2版本起,上述方法已被弃用,以下是新的API:

ActorRef ref = system.actorOf(new Props(JavaAPITestActor.class));
ref.tell(PoisonPill.getInstance());

以上代码在我的电脑上编译通过,所以你可能在 IDEA 中遇到了一些问题?尝试使用 javac 编译并检查是否能够通过。


抱歉,我应该说过,我确实阅读了文档并在提问之前尝试了那种方法,但是我不仅遇到了相同的编译错误,还被告知Actors已经被弃用,这就是为什么我尝试了其他方法。我会更新我的答案。 - Rich
我已经回到Eclipse,编译也很顺利!我想这可能是Idea的一个bug,但更可能是因为我在一个不太熟悉的IDE中做错了什么... - Rich
1
我很高兴在Akka中这不是一个问题 :-) - Viktor Klang
我有同样的问题。我认为这是一个IDE问题。编译和运行都很好。 - Antony Stubbs
是的,你应该尝试使用Eclipse :-) - Viktor Klang
显示剩余2条评论

6

如我在上面对评论的回复中提到的那样,这在使用Idea或者使用gradle编译时是无效的。实际上,这是一个编译错误,因为需要发送方ActorRef。我知道之前的答案都比较老了,而且我也不确定这是否是API的变化,所以如果有人遇到类似的问题,应该使用以下方式:

target.tell(PoisonPill.getInstance(), ActorRef.noSender());

参考文献: http://doc.akka.io/docs/akka/snapshot/java/lambda-actors.html#PoisonPill

此链接介绍了关于Akka框架中的“PoisonPill”的相关信息,它是一种用于停止Actor的消息。

0

2019年3月25日更新

@Viktor Klang和@yash.vyas的好答案有点过时了。这里是Scala 2.12.8和JDK8(1.8.0_172)的当前工作语法:

val accountB = context.actorOf(Props[BankAccount], "accountB")
accountB ! PoisonPill

你也可以写成:

...
accountB ! PoisonPill.getInstance

调用 tell 方法的默认方式也可以工作:

...
accountB.tell(PoisonPill.getInstance,ActorRef.noSender)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接