简体   繁体   中英

Locking ConcurrentHashMap for an exclusive read

I have several threads that save information to my ConcurrentHashMap<K,V> . I'm supposed to take a snapshot of the whole Map in a parent thread, process the information in it and eventually empty it from all values and keys.

How can I make sure that during the read (in the parent thread), it is not gonna be updated by any child-threads writing to it until I'm done with it? Is it possible to lock this data structure with a semaphore or a mutex?

Try something like this. Using a monitor to guard the map field so when you're taking the snapshot no one else can put values inside it.

public class Example<K, V> {
    private final Map<K, V> map = new HashMap<>();
    private final Object monitor = new Object();

    public Object snapshot() {
        synchronized (monitor) {
            // take the snapshot and return it
        }
    }

    public V put(K key, V value) {
        synchronized (monitor) {
            return map.put(key, value);
        }
    }
}

Also in this example you can simplify it by using a simple HashMap instead of a ConcurrentHashMap because you have the monitor guarding accesses to that field.

Use a ReadWriteLock .

This gives you a pair of locks:

  • A read lock, which many threads can acquire at the same time
  • A write lock, which only one thread can hold, and whilst held no thread can hold the read lock.

Despite the names, there is no reason these locks have to be used for reading and writing specifically:

  • Acquire (and release) the read lock for threads that are updating the map
  • Acquire (and release) the write lock for the thread which has to see the whole map at once.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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