所以我开始学习 Akka 并尝试 typesafe 中的示例。
因此 Hello Akka 应用程序具有以下代码:
import akka.actor.{ ActorRef, ActorSystem, Props, Actor, Inbox }
import scala.concurrent.duration._
case object Greet
case class WhoToGreet(who: String)
case class Greeting(message: String)
class Greeter extends Actor {
var greeting = ""
def receive = {
case WhoToGreet(who) => greeting = s"hello, $who"
case Greet => sender ! Greeting(greeting) // Send the current greeting back to the sender
}
}
object HelloAkkaScala extends App {
// Create the 'helloakka' actor system
val system = ActorSystem("helloakka")
// Create the 'greeter' actor
val greeter = system.actorOf(Props[Greeter], "greeter")
// Create an "actor-in-a-box"
val inbox = Inbox.create(system)
// Tell the 'greeter' to change its 'greeting' message
greeter.tell(WhoToGreet("akka"), ActorRef.noSender)
// Ask the 'greeter for the latest 'greeting'
// Reply should go to the "actor-in-a-box"
inbox.send(greeter, Greet)
// Wait 5 seconds for the reply with the 'greeting' message
val Greeting(message1) = inbox.receive(5.seconds)
println(s"Greeting: $message1")
// Change the greeting and ask for it again
greeter.tell(WhoToGreet("typesafe"), ActorRef.noSender)
inbox.send(greeter, Greet)
val Greeting(message2) = inbox.receive(5.seconds)
println(s"Greeting: $message2")
val greetPrinter = system.actorOf(Props[GreetPrinter])
// after zero seconds, send a Greet message every second to the greeter with a sender of the greetPrinter
system.scheduler.schedule(0.seconds, 1.second, greeter, Greet)(system.dispatcher, greetPrinter)
}
// prints a greeting
class GreetPrinter extends Actor {
def receive = {
case Greeting(message) => println(message)
}
}
现在我陷入了理解之间的区别,
greeter.tell(WhoToGreet("akka"), ActorRef.noSender)
和
inbox.send(greeter, Greet)
根据我的理解, Actor 在结束时开始自己的线程
val inbox = Inbox.create(system)
有人可以解释一下 Actorref.tell 究竟做了什么,然后 Inbox.send 行究竟实现了什么。
最佳答案
tell
的目的,也表示为 !
是向 Actor 发送消息。当参与者通过消息传递进行通信时,tell
是用于支持该消息传递的机制。它对调用者是异步的,因此一旦调用者调用 tell
,它们与目标actor实例对该消息的接收和处理分离。在这个特定的例子中,代码使用 tell 使欢迎者actor更新其内部状态。由于此交互不会导致任何类型的响应(接收方不会响应此请求向发送方发送消息),tell
单独在这里就足够了。
为了从迎宾员那里获得问候语响应,交互略有不同。在此交互中,发送方期待响应消息。这种类型的请求/响应交互可以通过 ask
处理(即 ?
),其中调用者获得 Future
当接收者回复但 ask
时,将完成返回这里没有使用。在此示例中,编码器通过使用 Inbox
获得请求/响应语义。相反,它可以充当 Actor ,并且消除了对 future 的需要。收件箱必须看起来像 ActorRef
到接收器,允许它使用以下行将响应路由回它:
sender ! Greeting(greeting)
sender()
方法返回 ActorRef
在当前正在处理的消息中发送的人。 Inbox
必须能够将自己表示为 ActorRef
为了这个工作。但正如我之前所说,你也可以使用 ask
在这里让请求/响应交互工作。我认为这只是一个选择问题。底线是tell
用于即发即弃交互模型,当需要请求/响应语义时,可以使用收件箱(或其他参与者或 ask
)。
关于scala - Akka中Actorref.tell和inbox.send的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27381815/