2015-04-25 18 views
3

我有一個演員,我想在地圖中存儲我的可變狀態。在Actor的接收方法的Future中關閉java.util.concurrent.ConcurrentHashMap?

客戶可以發送Get(key:String)Put(key:String,value:String)消息給這位演員。

我正在考慮以下選項。

  1. 不要在Actor的接收方法中使用futures。在這種情況下,如果我有大量的gets/puts,則可能會對延遲和吞吐量產生負面影響,因爲所有操作都將按順序執行。
  2. 使用java.util.concurrent.ConcurrentHashMap然後調用gets並放入Future

鑑於java.util.concurrent.ConcurrentHashMap是線程安全的,粒度更細的供應商水平,我想知道如果它仍然關閉在的ConcurrentHashMap內未來每個put和get帶來的問題。

我知道這是一個非常糟糕的主意,關閉在一個未來內部的可變狀態的演員,但我仍然有興趣知道是否在這種特殊情況下,它是正確的?

+1

0123爲什麼你在這種情況下有未來? 「HashMap」是否活在你的演員之外?如果一切都在你的演員內部,那麼就沒有必要使用期貨。在這種情況下,你不需要使用'ConcurrentHashMap' - 普通的舊'Map'就可以。 –

+0

@CemCatikkas - 根據演員模型的語義,演員郵箱中的消息將按順序處理。這也意味着,除非消息被完全處理,否則下一條消息將不得不等待。例如,想象一下,如果您有100個從Actor中可變映射中讀取的消息。在多核機器上,您應該可以同時讀取這些內容。使用期貨是這樣做的一種方式。 –

+0

訪問此散列映射是內存中操作。在未來包裝它會增加開銷,並可能是一種矯枉過正。除非你有合理的理由在這種情況下使用未來,否則你不應該這樣做。這就是說,你應該真的測量一下,然後確定你的案例的最佳用途。 –

回答

1

一般來說,java.util.concurrent.ConcurrentHashMap是爲了同時使用。只要您不嘗試將封閉件傳輸到另一臺機器,並且您可以通過它同時使用的含義來思考(例如,如果您讀取了一個值,請使用函數對其進行修改,然後再放回原處,您是否會想要使用replace(key, oldValue, newValue)方法來確保它在處理過程中沒有改變?),它在未來應該沒問題。

0

雖然可能有點晚,但在書Reactive Web Applications中,作者已經指出了對這個特定問題的間接性,使用pipeTo如下。

def receive = { 
    case ComputeReach(tweetId) => 
    fetchRetweets(tweetId, sender()) pipeTo self 
    case fetchedRetweets: FetchedRetweets => 
    followerCountsByRetweet += fetchedRetweets -> List.empty 
    fetchedRetweets.retweets.foreach { rt => 
     userFollowersCounter ! FetchFollowerCount(
     fetchedRetweets.tweetId, rt.user 
    ) 
} 
... 
} 

其中followerCountsByRetweet是演員的可變狀態。 fetchRetweets()這是一個Future的結果被傳送給同一個演員作爲FetchedRetweets消息,然後消息將作用於消息來修改acto的狀態,這將緩解狀態的任何併發操作

相關問題