演员实例数

Num of actor instance

我是 akka-actor 的新手,遇到了一些问题:

  1. 当我创建一个 actorSystem 并使用 actorOf(Props(classOf[AX], ...)) 在 main 方法中创建 actor 时,我的 actor AX 有多少个实例?
  2. 如果 Q1 的答案只有一个,这是否意味着我在 AX actor class 的定义中创建的任何数据结构都只会出现在一个线程中,我不应该担心并发问题?
  3. 如果我的演员的一个动作(接收方法中的一个案例)是一项耗时的任务并且需要很长时间才能完成怎么办?我的单个 Actor 实例在完成该任务之前不会响应吗?
  4. 如果问题 3 的答案是正确的,我应该怎么做才能防止我的演员不回应?我应该启动另一个线程并向其发送另一条消息直到完成任务吗?有没有我应该遵循的最佳实践?
  1. 一个实例(如果你在你的道具中声明一个路由器然后(可能)不止一个)
  2. 是的。这是演员的优势之一。
  3. 是的。 Actor 将按顺序处理消息。
  4. 您可以使用scala.concurrent.Future(以后不要使用actor state)或者将工作委托给子actor(主要actor可以管理状态并可以响应消息)。未来或儿童演员取决于用例。
  1. 是的,每次调用'actorOf'方法,actor系统只会创建1个actor实例。但是,当使用路由器时,可以创建 1 个路由器将负载分散到任意数量的参与者。所以在那种情况下,可以构造多个实例,但是 'normally' 使用 actorOf 只会创建 1 个实例。

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

  3. A​​kka 是一个高度并发和分布式的框架,一切都是异步和非阻塞的,你必须在你的应用程序中做同样的事情。 Scala 和 Akka 提供了几种解决方案来做到这一点。每当你在一个 actor 中有一个耗时的任务时,你可以将耗时的任务委托给另一个 actor 只是为了这个目的,使用 Futures 或使用 Scala 的 'async/await/blocking'。使用 'blocking' 时,您会提示 compiler/runtime 已完成阻塞操作,并且 运行time 可能会启动其他线程以防止线程饥饿。 Scala Concurrent programming book is an excellent guide to learn this stuff. Also look at the concurrent package ScalaDocs and Neophyte's Guide to Scala。 如果 actor 真的必须等待耗时的任务完成,那么是的,您的 actor 只能在任务完成时做出响应。但这是一种非常'request-response'的思维方式。尝试摆脱这种情况。参与者还可以立即响应,指示任务已经开始,并在任务完成后发送一条附加消息。 对于耗时任务,始终确保使用不同的线程池,这样 ActorSystem 就不会被阻塞,因为它的所有可用线程都被耗时任务用完了。对于 Future,您可以提供一个单独的 ExecutionContext(不要为此使用 ActorSystem 的 Dispatch 上下文!),但通过 Akka 的配置,您还可以将某些 actor 配置为 运行 在不同的线程池上。

  4. 见3.

成功!