如何从ConcurrentHashMap<String, Set<String>>中移除用作值的Set?
How to remove Set, which is used as value, from ConcurrentHashMap<String, Set<String>>?
让我们考虑以下代码:
ConcurrentHashMap<String, Set<String>> map = new ConcurrentHashMap<>();
// Add element: {mapKey, setValue}
map.computeIfAbsent(mapKey, new Function<String, Set<String>>() {
@Override
public Set<String> apply(String mapK) {
return ConcurrentHashMap.newKeySet();
}
}).add(setValue);
// Remove element: {mapKey, setValue}
Set<String> updatedSet = map.computeIfPresent(mapKey, new BiFunction<String, Set<String>, Set<String>>() {
@Override
public Set<String> apply(String mapK, Set<String> old) {
old.remove(setValue);
return old;
}
});
// I need remove mapKey, but I cannod do this like this, because of race condition bug
if (updatedSet.isEmpty()) {
map.remove(mapKey);
}
所以,我们可以看到:
- 我们有
ConcurrentHashMap<String, Set<String>>
地图,其中地图的 key
为 String
,value
为 ConcurrentHashSet
。
- 我需要删除
set
,这是 map
的值,当 set
是 empty
。
- 由于竞争条件错误,我无法实现
set
的简单删除。
我的问题有什么好的解决办法吗?
如果映射器 returns null
,computeIfPresent
删除条目。如果要删除条目,请从映射器中 return null
而不是在单独的步骤中执行删除。
(另外,你真的应该将 .add(setValue)
折叠到你的 computeIfAbsent
映射器中,并使用 compute
而不是 computeIfAbsent
,因为你没有做任何事情立即保护 add
调用。使用 merge
也是一种选择。)
让我们考虑以下代码:
ConcurrentHashMap<String, Set<String>> map = new ConcurrentHashMap<>();
// Add element: {mapKey, setValue}
map.computeIfAbsent(mapKey, new Function<String, Set<String>>() {
@Override
public Set<String> apply(String mapK) {
return ConcurrentHashMap.newKeySet();
}
}).add(setValue);
// Remove element: {mapKey, setValue}
Set<String> updatedSet = map.computeIfPresent(mapKey, new BiFunction<String, Set<String>, Set<String>>() {
@Override
public Set<String> apply(String mapK, Set<String> old) {
old.remove(setValue);
return old;
}
});
// I need remove mapKey, but I cannod do this like this, because of race condition bug
if (updatedSet.isEmpty()) {
map.remove(mapKey);
}
所以,我们可以看到:
- 我们有
ConcurrentHashMap<String, Set<String>>
地图,其中地图的key
为String
,value
为ConcurrentHashSet
。 - 我需要删除
set
,这是map
的值,当set
是empty
。 - 由于竞争条件错误,我无法实现
set
的简单删除。
我的问题有什么好的解决办法吗?
null
,computeIfPresent
删除条目。如果要删除条目,请从映射器中 return null
而不是在单独的步骤中执行删除。
(另外,你真的应该将 .add(setValue)
折叠到你的 computeIfAbsent
映射器中,并使用 compute
而不是 computeIfAbsent
,因为你没有做任何事情立即保护 add
调用。使用 merge
也是一种选择。)