[英]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);
}
- 此实现是线程安全的吗?
- 是否需要
synchronized
? 如果将其删除将有什么不好的后果?- 如果
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.