【问题标题】:How to deep copy a hashmap when working with multiple threads使用多个线程时如何深度复制哈希图
【发布时间】:2012-05-04 19:29:06
【问题描述】:

在我的应用程序中,我有两个线程。线程 1 正在向线程 2 传输数据。数据传输后,线程 1 中的数据在线程 2 中被清除。线程 1 继续在 HashMap 中放置更多数据,以便稍后传输到线程 2。与此同时,线程 2 对数据进行了它需要做的事情。我下面的代码是线程 2 中发生线程之间数据传输的部分。整个应用程序工作得很好,但我的问题是,有没有更好的方法来为线程 2 制作线程 1 数据的副本,而不使用关键字 new 来创建一个全新的对象?

我认为这样做可能会导致发生更多垃圾收集?我不应该担心这个吗?

synchronized(this){
    // Make a copy of the data map then clear it.
    cachedData = new HashMap<String,ArrayList<Float>>(data);
    data.clear();
}

【问题讨论】:

  • 根据您的需要,您也许可以使用Map.Entry-s 的某种同步队列而不是地图来实现更连续的数据传输。
  • 我明白了,我回顾了一些我的旧帖子,删除了一个我意识到有点愚蠢的帖子,并对答案进行评级。感谢您与我分享这些信息。

标签: java multithreading copy hashmap deep-copy


【解决方案1】:

因此,如果您要从多个线程访问此 data HashMap,那么您将必须在 每个 访问时设置一个 synchronized 块。仅仅因为您在此处获取缓存副本并不意味着其他线程可以在不同步的情况下使用data

如果您想同时使用HashMap 而不必围绕每个使用情况进行同步,那么您应该使用ConcurrentHashMap

整个应用程序运行良好,但我的问题是,有没有更好的方法来为线程 2 制作线程 1 数据的副本,而不使用关键字 new 来创建一个全新的对象?

考虑到我上面提到的注意事项,如果您想拍摄HashMap 的快照,以便您可以处理特定线程中的内容,那么您提到的模式很好并且经常使用。当您需要遍历 Collection 并在循环内对其进行修改但不执行 iterator.remove() 时,也会使用此模式。

如果您只需要键或值,请确保获取data.keySet()data.values() 的副本。

【讨论】:

  • 是的,我只是想要一个数据快照来处理。我也在同步所有线程中数据的每次访问。
【解决方案2】:

为什么不只是:

    synchronized(this){
        cachedData = data;
        data = new HashMap<String,ArrayList<Float>>();
    }

这与您拥有的类似,但不涉及数据复制。

我不会太担心new(除非您可以通过分析证明这是一个问题)。

【讨论】:

  • 我没有遇到任何特别的问题。我只是不确定这是否是处理此问题的好方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-04
  • 1970-01-01
  • 2023-04-10
  • 2011-04-19
  • 1970-01-01
相关资源
最近更新 更多