我对使用Scala中的演员感到有些不安。我已阅读关于如何做东西的文档,但我想我也需要一些不要规则以便随意使用它们。 我想我恐怕我会以错误的方式使用它们,我甚至不会注意到它。斯卡拉演员 - 最差的做法?
你能想到一些东西,如果适用,会导致打破Scala演员带来的好处,甚至导致错误的结果?
我对使用Scala中的演员感到有些不安。我已阅读关于如何做东西的文档,但我想我也需要一些不要规则以便随意使用它们。 我想我恐怕我会以错误的方式使用它们,我甚至不会注意到它。斯卡拉演员 - 最差的做法?
你能想到一些东西,如果适用,会导致打破Scala演员带来的好处,甚至导致错误的结果?
避免!?
尽可能。你将得到一个锁定的系统!
总是从一个Actor子系统线程发送消息。如果这意味着创建通过Actor.actor
方法的瞬态演员那就这样吧:
case ButtonClicked(src) => Actor.actor { controller ! SaveTrade(trdFld.text) }
添加“其他信息”处理你的演员的反应。否则,就不可能搞清楚,如果你要发送消息到错误演员:
case other => log.warning(this + " has received unexpected message " + other
不要为你的主要参与者,sublcass Actor
改用Actor.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 }
}
我知道这并不能真正回答这个问题,但至少应该重视基于消息的并发性比基于共享内存线程的并发性更不易发生错误的事实。
我想您已经在斯卡拉编程看到演员的准则,但备案:在处理消息
react {}
而不是receive {}
。您好, 谢谢您的快速答复 - 这让真正有用的点。 我在想,“共享状态”也是不能做的......但我并不完全知道这代表什么意思在代码级别 - 也许, - 作为消息类别C与私人领域F和这个领域的一个古典的getter(getF) - 从一个演员,发送一个实例C - 来自演员演员,接收C并调用getF ? 这是否意味着“共享状态”? 谢谢! – teo 2009-10-11 07:16:13
共享状态是由多个线程访问的状态。它不像共享可变状态那么糟糕,但它需要关于一致性的推理,除非它只在构建之后共享,并且从今以后不可变。因此,在消息中发送对自己的引用不会是最明智的举动,尽管引用可变对象比引用不可变对象更糟糕。 – DigitalRoss 2009-10-11 07:55:54
您的其他观点立即有意义,但我很好奇您总是从Actor线程发送消息的第二点。 这里的主要动机是什么,表现/清晰度/其他?我不太理解。 – Michael 2009-10-13 15:49:16
我看到你在斯卡拉遭受了很多写作者代码! :-) – 2009-10-13 21:15:03
* @ Michael * - 如果您没有明确声明一个Actor,则会为您创建一个,并将其绑定到'Thread'作为'ThreadLocal'。我完全不清楚这种方法在逻辑上是安全的还是没有内存泄漏。当演员在“react”中等待时,显式声明一个 – 2009-10-14 07:27:20