如何在ConcurrentHashMap中基于getOrDefault()实现原子getOrDefaultWithPut()?

hen*_*xin 0 java collections synchronized concurrenthashmap java.util.concurrent

ConcurrentHashMap支持atomic getOrDefault(Object key, V defaultValue),其中

返回指定键映射到的值,如果此映射不包含键的映射,则返回给定的默认值.

我的问题是:

如何ConcurrentHashMap通过提供原子操作来增强,比方说getOrDefaultWithPut(Object key, V defaultValue),哪个

"返回指定键映射,或第一次价值放在了给定的默认值到地图中,然后返回默认值,如果此映射包含的key.`没有映射"


我的解决方案

目前我有一Wrapper

 private ConcurrentMap<K, V> map = new ConcurrentHashMap<>();
Run Code Online (Sandbox Code Playgroud)

方法是:

public synchronized K getOrDefaultWithPut(K key, V defaultValue)
{
    map.putIfAbsent(key, defaultValue);
    return map.get(key);
}
Run Code Online (Sandbox Code Playgroud)
  1. 这个实现是否是线程安全的?
  2. synchronized必要吗?如果它被删除会发生什么不好?
  3. 如果getOrDefaultWithPut(K key, V defaultValue)是唯一的公共方法Wrapper,这个实现是线程安全的并且是synchronized必要的吗?

Sot*_*lis 6

只是用 computeIfAbsent

如果指定的键尚未与值关联,则尝试使用给定的映射函数计算其值,并将其输入此映射,除非null.整个方法调用以原子方式执行[...]

返回

与指定键关联的当前(现有或已计算)值,或者null如果计算值为null

提供一个mappingFunction生成默认值的,这将满足您的要求.

返回指定键映射到的值

这是现有的价值.

或者首先将给定的默认值放入映射中,然后如果此映射不包含键的映射,则返回默认值

如果没有null,该方法将插入计算值(默认值),并返回该计算值.


您不需要synchronized这个解决方案.方法调用是原子的,因此它是线程安全的.