没有预先推出的解决方案,但可以使用ConcurrentMap<K, Set<V>> 实现简单值的线程安全并发,其中Set<V> 值由ConcurrentMap<V, Boolean> 使用Collections.newSetFromMap(Map<V,Boolean>) 生成。
然后,要以原子方式设置每个值,请使用ConcurrentMap.computeIfAbsent(K, Function<? super K, ? extends Set<V>>):
ConcurrentMap<String, Set<Integer>> multimap = new ConcurrentHashMap<>();
Set<Integer> fooValues = multimap.computeIfAbsent("foo", key -> Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>()));
如果你希望你的值有一个稳定的迭代顺序,你可以使用 ConcurrentSkipListSet 来保存值:
ConcurrentMap<String, NavigableSet<Integer>> multimap = new ConcurrentHashMap<>();
NavigableSet<Integer> fooValues = multimap.computeIfAbsent("foo", key -> new ConcurrentSkipListSet<>());
同样,为了以线程安全的方式删除 Set<V> 值持有者实例,您可以使用 ConcurrentMap.computeIfPresent(K, BiFunction<? super K,? super Set<V>,? extends Set<V>>):
public static <K, V> void remove(final ConcurrentMap<K, Collection<? extends V>> multimap, final K key,
final V value) {
multimap.computeIfPresent(key, (k, oldValues) -> {
final Collection<? extends V> newValues;
if (oldValues.remove(value) && oldValues.isEmpty()) {
// Remove the empty set from the multimap
newValues = null;
} else {
newValues = oldValues;
}
return newValues;
});
}
注意there is no "ConcurrentHashSet" class provided by the Java core libraries。