在Future的Actor接收方法中关闭java.util.concurrent.ConcurrentHashMap?

时间:2015-04-25 10:35:05

标签: performance scala thread-safety akka concurrenthashmap

我是一名演员,我想在地图中存储我的可变状态。

客户端可以向此actor发送Get(key:String)Put(key:String,value:String)条消息。

我考虑以下选项。

  1. 不要在Actor的接收方法中使用未来。在这种情况下,如果我有大量的gets/puts,可能会对延迟和吞吐量产生负面影响,因为所有操作都将按顺序执行。
  2. 使用java.util.concurrent.ConcurrentHashMap然后调用gets并放入Future
  3. 鉴于java.util.concurrent.ConcurrentHashMap是线程安全的并提供更精细的粒度级别,我想知道在为每个put和get创建的Future中关闭concurrentHashMap是否仍然是一个问题。

    我意识到在演员的未来里面关闭可变状态是一个非常糟糕的事实但是我仍然有兴趣知道是否在这种特殊情况下它是否正确?

2 个答案:

答案 0 :(得分:1)

通常,java.util.concurrent.ConcurrentHashMap用于并发使用。只要你不尝试将闭包传输到另一台机器,并且你想通过它同时使用的含义(例如,如果你读取一个值,使用一个函数来修改它,然后把它放回去,你呢?想要使用replace(key, oldValue, newValue)方法来确保它在处理过程中没有改变吗?),它在期货中应该没问题。

答案 1 :(得分: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是演员的可变状态。作为Future的fetchRetweets()的结果通过管道传递给与FetchedRetweets消息相同的actor,然后该消息对消息进行操作以修改acto的状态。这将减轻对任何并发操作的影响。国家