ConcurrentHashMap supports atomic getOrDefault(Object key, V defaultValue)
, which
Returns the value to which the specified key is mapped, or the given default value if this map contains no mapping for the key.
My problem is:
How can I enhance
ConcurrentHashMap
by providing an atomic operation, saygetOrDefaultWithPut(Object key, V defaultValue)
, which"Returns the value to which the specified key is mapped, or first put the the given default value into the map and then return the default value if this map contains no mapping for the key.`"
My solution:
Currently I have a Wrapper
class of
private ConcurrentMap<K, V> map = new ConcurrentHashMap<>();
The method is:
public synchronized K getOrDefaultWithPut(K key, V defaultValue)
{
map.putIfAbsent(key, defaultValue);
return map.get(key);
}
- Is this implementation thread-safe?
- Is
synchronized
necessary? What bad would happen if it is removed?- If
getOrDefaultWithPut(K key, V defaultValue)
is the only public method ofWrapper
, is this implementation thread-safe and issynchronized
necessary?
Just use computeIfAbsent
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 [...]Returns
the current (existing or computed) value associated with the specified key, or
null
if the computed value isnull
Provide a mappingFunction
which generates your default value and this will satisfy your requirement.
Returns the value to which the specified key is mapped
That's the existing value.
or first put the the given default value into the map and then return the default value if this map contains no mapping for the key
The method will insert the computed value (the default), if not null
, and return that computed value.
You won't need synchronized
with this solution. The method invocation is atomic and it's therefore thread safe.