Scala 演员 - 最糟糕的做法? [关闭]

Posted

技术标签:

【中文标题】Scala 演员 - 最糟糕的做法? [关闭]【英文标题】:Scala actors - worst practices? [closed] 【发布时间】:2010-12-05 16:13:08 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

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

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

Actor 在处理消息时不应阻塞。您可能想要阻止的地方尝试安排稍后接收消息。 尽可能使用react 而不是receive 。 仅通过消息与参与者交流。 首选不可变消息。 使消息自包含。

【讨论】:

您好,感谢您的快速回答 - 它提出了非常有用的观点。我在想“共享状态”也是不应该做的事情......但我不完全知道这在代码级别意味着什么 - 也许 - 将带有私有字段 F 和经典 getter 的类 C 作为消息对于这个字段 (getF) - 从一个演员,发送一个 C 的实例 - 从演员演员,接收 C 并调用 getF ?这是否意味着“共享状态”?谢谢! 共享状态是被多个线程访问的状态。它不像共享可变状态那么糟糕,但它需要对一致性进行推理,除非它仅在构造后共享并且从此不可变。因此,在消息中发送对自己的引用并不是最明智的举措,尽管对可变对象的引用比对不可变对象的引用更糟糕。【参考方案2】:

尽可能避免使用!?。您锁定系统!

始终从 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 用于您的主要演员,而是使用子类Actor。这样做的原因是只有通过子类化才能提供一个明智的toString 方法。同样,如果您的日志中充斥着以下语句,那么调试 actor 会非常困难:

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

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

始终确保您可以在其react 循环之外与您的actor 通信以查找其状态。例如,我总是声明一个要通过 MBean 调用的方法,该方法类似于以下代码 sn-p。否则很难判断您的演员是否正在运行、是否已关闭、是否有大量消息等。

.

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 - 否则他们可能会默默地失败,这意味着您的程序没有按照您的想法执行并且可能会因为消息保留在演员的邮箱中而内存不足。

我认为,herehere

【讨论】:

您的其他观点立即变得有意义,但我很好奇您始终从 Actor 线程内发送消息的第二点。这里的主要动机是什么,性能/清晰度/其他?我不太明白。 我看到您在 Scala 中编写 Actor 代码时遭受了很多痛苦! :-) @Michael - 如果您自己没有明确声明一个 Actor,则会为您创建一个并绑定到 Thread 作为 ThreadLocal。我完全不清楚这种方法在逻辑上是安全的还是没有内存泄漏。显式声明一个要简单得多 (myActor.getState == scala.actors.Actor.State.Suspended) 当actor在react中等待时为真,所以我们真的需要你建议的方法来查找状态吗? 本题***.com/q/6287930/243233的代码有问题吗?

以上是关于Scala 演员 - 最糟糕的做法? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

使用 Netty 和 Scala 演员的异步 http 请求

Scala Play Framework,在哪里创建演员?

scala演员和持久性上下文

Scala 演员和环境参考

Clojure 的代理与 Scala 的演员相比如何?

Akka Scala 演员中的死信