我對使用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