【问题标题】:Num of actor instance演员实例数
【发布时间】:2015-06-29 15:21:31
【问题描述】:

我是 akka-actor 的新手,对一些问题感到困惑:

  1. 当我创建一个actorSystem,并在main方法中使用actorOf(Props(classOf[AX], ...))创建actor时,我的actor AX有多少个实例?
  2. 如果 Q1 的答案只有一个,这是否意味着我在 AX 角色类的定义中创建的任何数据结构都只会出现在一个线程中,我不应该担心并发问题?
  3. 如果我的演员的一个动作(接收方法中的一个案例)是一项耗时的任务并且需要很长时间才能完成怎么办?我的单个 Actor 实例会在完成该任务之前没有响应吗?
  4. 如果 Q3 的答案是正确的,我应该怎么做才能防止我的演员没有回应?我是否应该启动另一个线程并将另一条消息发回给它,直到完成任务?那里有我应该遵循的最佳做法吗?

【问题讨论】:

    标签: scala akka actor


    【解决方案1】:
    1. 是的,每次调用 'actorOf' 方法时,actor 系统只会创建 1 个 actor 实例。但是,当使用路由器时,可以创建 1 个将负载分散到任意数量的参与者的路由器。因此,在这种情况下,可以构造多个实例,但“通常”使用 actorOf 只会创建 1 个实例。

    2. 是的,在一个 Actor 内,您不必担心并发性,因为 Akka 保证任何 Actor 一次只处理 1 条消息。您必须注意不要以某种方式从参与者外部的代码中改变参与者的状态。因此,无论何时公开演员状态,始终使用不可变类来执行此操作。案例类非常适合这一点。但也要注意在从 Actor 内部完成 Future 时修改 Actor 状态。由于 Future 在它自己的线程上运行,当 Future 完成并且参与者同时处理下一条消息时,您可能会遇到并发问题。 Actor 一次在 1 个线程上执行,但每次执行 Actor 时,这可能是一个不同的线程。

    3. Akka 是一个高度并发和分布式的框架,一切都是异步和非阻塞的,您必须在应用程序中做同样的事情。 Scala 和 Akka 提供了几种解决方案来做到这一点。每当你在一个actor中有一个耗时的任务时,你可以将耗时的任务委托给另一个actor来实现这个目的,使用Futures或者使用Scala的'async/await/blocking'。使用“阻塞”时,您会提示编译器/运行时完成阻塞操作,并且运行时可能会启动额外的线程以防止线程饥饿。 Scala Concurrent programming book 是学习这些东西的绝佳指南。另请查看concurrent package ScalaDocsNeophyte's Guide to Scala。 如果演员真的必须等待耗时的任务完成,那么是的,您的演员只能在完成后做出响应。但这是一种非常“请求-响应”的思维方式。试着远离这个。参与者还可以立即响应,指示任务已开始,并在任务完成后发送附加消息。 对于耗时的任务,请务必使用不同的线程池,这样 ActorSystem 就不会被阻塞,因为它所有的可用线程都被耗时的任务用完了。对于 Future,您可以提供一个单独的 ExecutionContext(不要为此使用 ActorSystem 的 Dispatch 上下文!),但是通过 Akka 的配置,您还可以配置某些 Actor 以在不同的线程池上运行。

    4. 见 3。

    成功了!

    【讨论】:

      【解决方案2】:
      1. 一个实例(如果你在你的 props 中声明了一个路由器,那么(可能)不止一个)
      2. 是的。这是演员的优势之一。
      3. 是的。 Actor 将按顺序处理消息。
      4. 您可以使用 scala.concurrent.Future(以后不要使用 Actor 状态)或将工作委托给子 Actor(主要 Actor 可以管理状态并可以响应消息)。未来或子角色取决于用例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-13
        • 1970-01-01
        • 2021-05-15
        • 1970-01-01
        • 1970-01-01
        • 2015-03-21
        • 1970-01-01
        相关资源
        最近更新 更多