繁体   English   中英

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

[英]How to implement atomic getOrDefaultWithPut() based on getOrDefault() in ConcurrentHashMap?

ConcurrentHashMap支持原子getOrDefault(Object key, V defaultValue) ,它

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

我的问题是:

我如何通过提供原子操作来增强ConcurrentHashMap ,例如getOrDefaultWithPut(Object key, V defaultValue) ,它

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


我的解决方案:

目前,我有一个Wrapper

 private ConcurrentMap<K, V> map = new ConcurrentHashMap<>();

方法是:

public synchronized K getOrDefaultWithPut(K key, V defaultValue)
{
    map.putIfAbsent(key, defaultValue);
    return map.get(key);
}
  1. 此实现是线程安全的吗?
  2. 是否需要synchronized 如果将其删除将有什么不好的后果?
  3. 如果getOrDefaultWithPut(K key, V defaultValue)Wrapper的唯一公共方法,此实现是线程安全的并且需要synchronized吗?

只需使用computeIfAbsent

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

退货

与指定键相关联的电流(现有的或计算的)值,或null ,如果计算出的值是null

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

返回指定键映射到的值

那就是现有的价值。

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

该方法将插入计算值(默认值)(如果不为null ,然后返回该计算值。


您无需与此解决方案synchronized 方法调用是原子的,因此是线程安全的。

几乎。 您应该使用由putIfAbsent返回的值,而不是执行另一个.get ,并且您不需要synchronized它(在这种情况下,它还是毫无用处的,除非所有其他调用者都知道也要同步,这违背了它的目的) ConcurrentHashMap

public V getOrDefaultWithPut(K key, V defaultValue) 
{
  V val = map.putIfAbsent(key, defaultValue);
  return val == null ? defaultValue : val;
}

编辑computeIfAbsent可以工作,这只是简单一点,因为在这种情况下您不需要定义函数,而且我认为,它也可以提供更多的信息作为答案,因为它实际上可以解决原始问题。方法,而不是用其他方法代替它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM