3

在我的应用程序中,我有两个线程。线程 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();
}
4

2 回答 2

2

为什么不只是:

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

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

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

于 2012-05-04T19:31:13.453 回答
2

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

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

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

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

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

于 2012-05-04T19:32:26.923 回答