2012-05-04 34 views
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(); 
} 
+0

根据您的需要,您可能可以使用某种“Map.Entry”的同步队列来代替地图,以便更持续地传输数据。 – trutheality

+0

我明白了,我回过去看过我的一些旧帖子,删除了一个我认识的笨蛋,然后评价答案。感谢您与我分享这些信息。 –

回答

2

所以,如果你访问这个data从多个线程HashMap那么你将不得不对每访问一个​​块。仅仅因为您在这里抓取缓存副本并不意味着其他线程无需同步即可使用data

如果你想同时使用HashMap没有必须围绕每个用法进行同步,那么你应该使用ConcurrentHashMap

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

考虑到我上面提到的注意事项,如果你想采取HashMap快照,以便您可以在一个特定的线程的内容工作,那么你所提到的模式是很好,经常被使用。当您需要迭代Collection并在循环内部修改它时,也可以使用此模式,但不需要执行iterator.remove()

如果您只是需要密钥或值,请确保采取data.keySet()或的副本。

+0

是的,我只想要使用数据的快照。我正在同步所有线程中的数据访问。 –

2

为什么不干脆:

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

这与你有什么,但不涉及数据的复制。

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

+0

我没有遇到过特殊问题。我只是不确定这是否是处理这个问题的好方法。 –