49

我对在 Scala 中使用演员感到有点不安全。我已经阅读了有关如何做事的文档,但我想我还需要一些 DON'T 规则才能随意使用它们。我想我害怕我会以错误的方式使用它们,我什至不会注意到它。

你能想到一些东西,如果应用的话,会导致破坏 Scala 演员带来的好处,甚至是错误的结果?

4

2 回答 2

55
  • !?尽可能避免。你得到一个锁定的系统!

  • 始终从 Actor 子系统线程发送消息。如果这意味着通过该方法创建一个瞬态 Actor,Actor.actor那么就这样吧:

    case ButtonClicked(src) => Actor.actor { controller ! SaveTrade(trdFld.text) }

  • 为你的演员的反应添加一个“任何其他消息”处理程序。否则无法确定您是否正在向错误的参与者发送消息:

    case other => log.warning(this + " has received unexpected message " + other

  • 不要Actor.actor用于您的主要演员,而是使用 sublcass Actor。这样做的原因是只有通过子类化才能提供合理的toString方法。同样,如果您的日志中充斥着以下语句,那么调试参与者将非常困难:

    12:03 [INFO] Sending RequestTrades(2009-10-12) to scala.actors.Actor$anonfun$1

  • 记录系统中的参与者,明确说明他们将收到什么消息以及他们应该如何计算响应。使用参与者会导致将标准过程(通常封装在方法中)转换为跨多个参与者反应的逻辑。如果没有良好的文档,很容易迷失方向。

  • 始终确保您可以在其react循环之外与您的演员进行通信以找到其状态。例如,我总是声明一个要通过MBean如下代码片段调用的方法。否则很难判断您的演员是否正在运行、是否已关闭、是否有大量消息队列等。

.

def reportState = {
  val _this = this
  synchronized {
    val msg = "%s Received request to report state with %d items in mailbox".format(
                   _this, mailboxSize) 
    log.info(msg)
  }
  Actor.actor { _this ! ReportState }
}
  • 将你的演员链接在一起并使用trapExit = true- 否则他们可能会默默地失败,这意味着你的程序没有按照你的想法做,并且可能会因为消息保留在演员的邮箱中而内存不足。

  • 我认为这里这里强调了围绕使用演员做出的设计决策的其他一些有趣的选择

于 2009-10-12T07:44:40.980 回答
12

我知道这并不能真正回答这个问题,但您至少应该相信基于消息的并发比基于共享内存线程的并发更不容易出现奇怪的错误。

我想你已经在Programming in Scala中看到了演员指南,但为了记录:

  • 参与者在处理消息时不应阻塞。您可能想要阻止的地方尝试安排稍后收到消息。
  • 尽可能使用react {}而不是使用receive {}
  • 仅通过消息与参与者交流。
  • 更喜欢不可变的消息。
  • 使消息自包含。
于 2009-10-10T22:38:37.903 回答