简体   繁体   English

如何在处理多个线程时深层复制hashmap

[英]How to deep copy a hashmap when working with multiple threads

In my application I have two threads. 在我的应用程序中,我有两个线程。 Thread 1 is transferring data to Thread 2. After the data is transferred the data in thread 1 is cleared within thread 2. Thread 1 goes on its merry way placing more data in the HashMap as it comes in to be transferred to Thread 2 later. 线程1正在将数据传输到线程2.传输数据后,线程1中的数据在线程2中被清除。线程1以其快乐的方式将更多数据放入HashMap中,因为它稍后将被传输到线程2。 In the meantime, Thread 2 does what it needs to do with the data. 与此同时,线程2完成了对数据所需的操作。 The code I have below is the part in thread 2 where that data transfer between threads happens. 我下面的代码是线程2中的部分,其中线程之间的数据传输发生。 The entire application works just fine, but my questions is, is there a better way to make this copy of the thread 1 data for thread 2 without using the keyword new to create a whole new object? 整个应用程序工作正常,但我的问题是,有没有更好的方法来为线程2创建线程1数据的这个副本而不使用关键字new来创建一个全新的对象?

I figure doing this might cause more garbage collections to occur? 我想这样做可能会导致更多的垃圾收集? Should I not worry about this? 我不应该担心这个吗?

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

Why not just: 为什么不呢:

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

This is similar to what you have, but involves no copying of the data. 这与您拥有的类似,但不涉及复制数据。

I wouldn't worry about the new too much (not unless you can prove through profiling that it's a problem). 我不会担心new太多(除非你能通过剖析证明这是一个问题)。

So if you are accessing this data HashMap from multiple threads then you will have to have a synchronized block on every access. 因此,如果您从多个线程访问此data HashMap ,则必须在每次访问时都有一个synchronized块。 Just because you are grabbing a cached copy here does not mean that other threads get to use the data without synchronization. 仅仅因为你在这里抓取一个缓存副本并不意味着其他线程可以在没有同步的情况下使用data

If you want to have concurrent usage of HashMap without having to synchronize around each usage then you should be using a ConcurrentHashMap . 如果你想同时使用HashMap 不必围绕每个用法进行同步,那么你应该使用ConcurrentHashMap

The entire application works just fine, but my questions is, is there a better way to make this copy of the thread 1 data for thread 2 without using the keyword new to create a whole new object? 整个应用程序工作正常,但我的问题是,有没有更好的方法来为线程2创建线程1数据的这个副本而不使用关键字new来创建一个全新的对象?

Taking into account the cautions I mentioned above, if you want to take a snapshot of a HashMap so you can work with the contents in a specific thread then the pattern you mention is fine and is often used. 考虑到我上面提到的注意事项,如果你想拍摄一个HashMap的快照,这样你就可以使用特定线程中的内容,那么你提到的模式很好并经常使用。 This pattern is also used when you need to iterate through a Collection and modify it inside of the loop but without doing an iterator.remove() . 当您需要遍历Collection并在循环内部修改它但不执行iterator.remove()时,也会使用此模式。

If you just need the keys or the values then make sure to take a copy of the data.keySet() or data.values() instead. 如果您只需要键或值,请确保获取data.keySet()data.values()的副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM