在给演员发送消息时,惊叹号(!
)和问号(?
)有什么区别?
myActor ! Hello(value1)
myActor ? Hello(value1)
不要介意,我抄袭了一个 [厉害的]官方文档 (查看更多信息请看发送消息部分):
消息可以通过以下方法之一发送给Actor。
!
表示“fire-and-forget”,即异步发送消息并立即返回。也称为tell
。
?
异步发送消息并返回表示可能回复的Future
。 也称为ask
。
从接收者的角度来看,它以相同的方式看待 tell
和 ask
消息。但是在接收到 tell
时,sender
的值将是发送消息的 Actor 的引用,而对于一个 ask
,sender
被设置为任何回复都会被发送到提问者 Actor 中创建的 Future
。
ask
的优点在于易于知道您接收到的响应确实是您所请求的消息的结果,而使用 tell
,您可能需要使用唯一的 ID 才能实现类似的结果。但是,对于 ask
,您需要在接收到响应之前设置一个 timeout
,否则 Future
将失败。
在下面的代码中,使用 tell
和 ask
实现了相同的效果。
import akka.actor.{Props, Actor}
import scala.concurrent.duration._
import akka.pattern.ask
class TellActor extends Actor {
val recipient = context.actorOf(Props[ReceiveActor])
def receive = {
case "Start" =>
recipient ! "Hello" // equivalent to recipient.tell("hello", self)
case reply => println(reply)
}
}
class AskActor extends Actor {
val recipient = context.actorOf(Props[ReceiveActor])
def receive = {
case "Start" =>
implicit val timeout = 3 seconds
val replyF = recipient ? "Hello" // equivalent to recipient.ask("Hello")
replyF.onSuccess{
case reply => println(reply)
}
}
}
class ReceiveActor extends Actor {
def receive = {
case "Hello" => sender ! "And Hello to you!"
}
}