Scala 在ActorSystem中有没有一种方法可以将值从actor发送到actorRef

Scala 在ActorSystem中有没有一种方法可以将值从actor发送到actorRef,scala,akka,Scala,Akka,我有两个演员,编码如下 class Actor1 extends Actor { val r : ActorRef = actorOf (Props[Actor2], "master") def receive: Receive = { case class Mul (a,b) => r ! CalcMul (a,b) case class MulReply (ans) => prin

我有两个演员,编码如下

class Actor1 extends Actor {
    val r : ActorRef = actorOf (Props[Actor2], "master")

    def receive: Receive = {
        case class Mul (a,b) =>
            r ! CalcMul (a,b)

        case class MulReply (ans) =>
            println("Multiply result : " + ans)
            // want to send "ans" value to testObject..
    }
}

class Actor2 extends Actor {

    def receive: Receive = {
        case class CalcMul (a,b) =>
            sender ! MulReply (a*b)
    }
}

object testObject extends App {
    val a = ActorSystem("ActorSystem").actorOf(Props[Actor1], "root")

    a ! CalcMul (5, 15)
    // how to receive "ans" value here?
}

我可以在
Actor1
中接收并打印结果,但需要在
testObject
中使用这些值,以便将来操作时使用它们。无法在
testObject
中使用
receive
方法从
Actor2
接收
Actor1
中的消息,因此无法使用
tell
方法发送消息。

当您希望从参与者接收响应时,可以使用ask模式

import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import akka.pattern._
import akka.util.Timeout

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.concurrent.duration.SECONDS


case class CalsMul(a: Int, b: Int)

  class Actor1 extends Actor {
    val r: ActorRef = context.actorOf(Props[Actor2], "master")

    def receive: Receive = {
      case req: CalsMul =>
        println("received message by Actor1")
        r forward req
    }
  }

  class Actor2 extends Actor {

    def receive: Receive = {
      case request: CalsMul =>
        println("received message by Actor2")
        Future.successful(request.a * request.b) pipeTo sender
    }
  }

  object testObject extends App {
    implicit val system: ActorSystem = ActorSystem("ActorSystem")
    val a: ActorRef = system.actorOf(Props[Actor1], "root")
    implicit val timeout: Timeout = Timeout(20, SECONDS)

    println(system, "sending message to Actor1")
    val ans: Future[Int] = (a ? CalsMul(5, 15)).mapTo[Int] // as you are returning the multiplication of a*b

    ans.foreach(println)
  }

注意:建议不要将CPU限制的操作与参与者一起使用,因为它可能会对应用程序的性能产生不利影响

因为您希望接收参与者的响应,因此可以使用ask模式

import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import akka.pattern._
import akka.util.Timeout

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.concurrent.duration.SECONDS


case class CalsMul(a: Int, b: Int)

  class Actor1 extends Actor {
    val r: ActorRef = context.actorOf(Props[Actor2], "master")

    def receive: Receive = {
      case req: CalsMul =>
        println("received message by Actor1")
        r forward req
    }
  }

  class Actor2 extends Actor {

    def receive: Receive = {
      case request: CalsMul =>
        println("received message by Actor2")
        Future.successful(request.a * request.b) pipeTo sender
    }
  }

  object testObject extends App {
    implicit val system: ActorSystem = ActorSystem("ActorSystem")
    val a: ActorRef = system.actorOf(Props[Actor1], "root")
    implicit val timeout: Timeout = Timeout(20, SECONDS)

    println(system, "sending message to Actor1")
    val ans: Future[Int] = (a ? CalsMul(5, 15)).mapTo[Int] // as you are returning the multiplication of a*b

    ans.foreach(println)
  }

注意:建议不要将CPU绑定的操作与参与者一起使用,因为这可能会对应用程序的性能产生不利影响

是的,您可以使用ask执行查看:是的,您可以使用ask执行查看:相反,如果您有CPU绑定的操作,请不要尝试用一条消息来完成它们。找到一些方法将问题分解成几个部分,或者将工作交给多个孩子,或者给自己发送消息,触发子任务。让孩子们分担工作可以利用更多的核心;告诉自己处理它提供了相当于Thread.yield()调用的功能,因为调度程序有机会在不同的步骤之间将线程切换到不同的参与者。不,我们不应该在将来执行CPU绑定的操作,因为这并不是为了实现这一点,我们应该使用Futures进行I/O绑定操作,因为这些都是阻塞调用,并且可以在线程上运行,无论我们需要多少小块给子参与者cpu绑定操作在将来不是一个好的做法@罗伯克劳福德没有说要用未来。我不知道你是从哪里得到我的想法的。Ask调用总是返回未来,你说不要试图在单个消息(Ask消息)中完成CPU限制的操作,所以我想到了未来@相反,如果您有CPU限制的操作,不要试图用一条消息来完成它们。找到一些方法将问题分解成几个部分,或者将工作交给多个孩子,或者给自己发送消息,触发子任务。让孩子们分担工作可以利用更多的核心;告诉自己处理它提供了相当于Thread.yield()调用的功能,因为调度程序有机会在不同的步骤之间将线程切换到不同的参与者。不,我们不应该在将来执行CPU绑定的操作,因为这并不是为了实现这一点,我们应该使用Futures进行I/O绑定操作,因为这些都是阻塞调用,并且可以在线程上运行,无论我们需要多少小块给子参与者cpu绑定操作在将来不是一个好的做法@罗伯克劳福德没有说要用未来。我不知道你是从哪里得到我的想法的。Ask调用总是返回未来,你说不要试图在单个消息(Ask消息)中完成CPU限制的操作,所以我想到了未来@罗伯克劳福德