Java – Cache using ConcurrentHashMap

collectionsconcurrencyhashmapjavamultithreading

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?

Best Answer

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.