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

Java 如何基于ConcurrentHashMap中的getOrDefault()实现原子getOrDefaultWithPut()?,java,collections,synchronized,java.util.concurrent,concurrenthashmap,Java,Collections,Synchronized,Java.util.concurrent,Concurrenthashmap,支持原子,这 返回指定键映射到的值,如果此映射不包含该键的映射,则返回给定的默认值 我的问题是: 如何通过提供原子操作来增强ConcurrentHashMap,比如getOrDefaultWithPutObject键,V defaultValue,它 返回指定键映射到的值,或者首先将给定的默认值放入映射中,如果此映射不包含键的映射,则返回默认值` 我的解决方案: 目前我有一个 这个实现是线程安全的吗? 是否需要同步?如果它被移除,会发生什么坏事? 如果getOrDefaultWithPutK键,

支持原子,这

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

我的问题是:

如何通过提供原子操作来增强ConcurrentHashMap,比如getOrDefaultWithPutObject键,V defaultValue,它

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

我的解决方案:

目前我有一个

这个实现是线程安全的吗? 是否需要同步?如果它被移除,会发生什么坏事? 如果getOrDefaultWithPutK键,V defaultValue是包装器的唯一公共方法,那么这个实现是线程安全的并且需要同步吗? 只用

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

返回

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

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

返回指定键映射到的值

这是现有的值

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

该方法将插入默认的计算值(如果不是null),并返回该计算值


您不需要与此解决方案同步。方法调用是原子的,因此是线程安全的。

。您应该使用putIfAbsent返回的值,而不是执行另一个.get,并且您不需要对其进行同步。无论如何,在这种情况下,它是相当无用的,除非所有其他调用方也知道要进行同步,这会破坏它作为ConcurrentHashMap的目的:


编辑:computeIfAbsent也能工作,这只是简单了一点,因为在这种情况下,您不需要定义函数,而且我认为,作为一个答案,它的信息量更大,因为它实际上用您原来的方法解决了问题,而不是用另一种方法来代替它。

通过使用synchronized,您似乎已经失去了并发哈希映射内部提供的所有并行性。此外,您应该在方法中使用getOrDefault。代码不起作用的唯一情况是,如果有人删除了语句map.putIfAbsent和map.getOrDefault之间的键,在这种情况下,您将获得一个默认值,但键不会出现在map中,这也可以根据您的用例理想地正确
 private ConcurrentMap<K, V> map = new ConcurrentHashMap<>();
public synchronized K getOrDefaultWithPut(K key, V defaultValue)
{
    map.putIfAbsent(key, defaultValue);
    return map.get(key);
}
public V getOrDefaultWithPut(K key, V defaultValue) 
{
  V val = map.putIfAbsent(key, defaultValue);
  return val == null ? defaultValue : val;
}