Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cache using ConcurrentHashMap

I have the following code:

public class Cache {

    private final Map map = new ConcurrentHashMap();

    public Object get(Object key) {

        Object value = map.get(key);
        if (value == null) {
            value = new SomeObject();
            map.put(key, value);
        }

        return value;
    }
}

My question is: The put and get methods of the map are thread safe, but since the whole block in not synchronized - could multiple threads add a the same key twice?

like image 441
CCC Avatar asked Nov 13 '14 17:11

CCC


People also ask

What is ConcurrentHashMap used for?

ConcurrentHashMap class is thread-safe i.e. multiple threads can operate on a single object without any complications. At a time any number of threads are applicable for a read operation without locking the ConcurrentHashMap object which is not there in HashMap.

Why ConcurrentHashMap is faster than HashMap?

HashMap performance is relatively high because it is non-synchronized in nature and any number of threads can perform simultaneously. But ConcurrentHashMap performance is low sometimes because sometimes Threads are required to wait on ConcurrentHashMap.

Is Java ConcurrentHashMap thread-safe?

ConcurrentHashMap class achieves thread-safety by dividing the map into segments, the lock is required not for the entire object but for one segment, i.e one thread requires a lock of one segment. In ConcurrenHashap the read operation doesn't require any lock.


1 Answers

As of Java 8, you can also prevent this addition of duplicate keys with:

public class Cache {

    private final Map map = new ConcurrentHashMap();

    public Object get(Object key) {

        Object value = map.computeIfAbsent(key, (key) -> {
          return new SomeObject();
        });

        return value;
    }
}

The API docs state:

If the specified key is not already associated with a value, attempts to compute its value using the given mapping function and enters it into this map unless null. The entire method invocation is performed atomically, so the function is applied at most once per key. Some attempted update operations on this map by other threads may be blocked while computation is in progress, so the computation should be short and simple, and must not attempt to update any other mappings of this map.

like image 66
AndrWeisR Avatar answered Oct 19 '22 13:10

AndrWeisR