78

向 Actor 发送消息时,感叹号 ( !) 和问号 ( )有什么区别??

myActor ! Hello(value1)
myActor ? Hello(value1)
4

2 回答 2

131

无耻地复制[awesome] 官方文档(查看发送消息部分了解更多信息):

消息通过以下方法之一发送到 Actor。

!表示“即发即弃”,例如异步发送消息并立即返回。也称为tell.

?异步发送消息并返回一个Future表示可能的回复。也称为ask.

于 2013-07-14T22:11:35.707 回答
26

从收件人的角度来看,它以相同的方式查看tellask发送消息。但是,当接收到 a 时tell, 的值sender将是发送消息的参与者的引用,而对于 a ask, 的sender设置为使得任何回复都会发送到Future发出请求的参与者中创建的。

有一个优势ask,很容易知道您收到的响应肯定是您询问的消息的结果,而使用 Tell,您可能需要使用唯一的 ID 才能获得类似的结果。但是,ask您需要设置 a ,如果没有收到响应,则timeout在此之后将失败。Future

tell在下面的代码中,使用 a和实现了相同的效果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!"
  }
}
于 2015-07-27T16:33:33.823 回答