java中是否有任何并发多值HashMap数据结构?

java中是否有任何并发多值HashMap数据结构?,java,data-structures,concurrenthashmap,Java,Data Structures,Concurrenthashmap,我需要有键值对,其中的值可以是一个集合。此数据结构应该是线程安全的,以便在多线程环境中将删除元素添加到集合中。 我的要求是创建一个订阅列表,在这里人们可以订阅不同的主题。此订阅列表应该是并发的、线程安全的和快速的。我正在考虑使用ConcurentHashMap和ConcurrentHashSet,这对我没有帮助,因为我必须将syncronization块放在顶层,它将阻止整个映射,直到put/remove操作完成。您编写了“值可以是一个集”,但不要提及键是什么。在任何情况下,Java中出现的第一

我需要有键值对,其中的值可以是一个集合。此数据结构应该是线程安全的,以便在多线程环境中将删除元素添加到集合中。

我的要求是创建一个订阅列表,在这里人们可以订阅不同的主题。此订阅列表应该是并发的、线程安全的和快速的。我正在考虑使用ConcurentHashMap和ConcurrentHashSet,这对我没有帮助,因为我必须将syncronization块放在顶层,它将阻止整个映射,直到put/remove操作完成。

您编写了“值可以是一个集”,但不要提及键是什么。在任何情况下,Java中出现的第一个映射Hashtable都是线程安全的wrt添加/删除/替换键、值对


可以使用所述的方法之一创建线程安全集。该集合是否作为值存储在hashmap中没有区别。

没有预滚解决方案,但是可以使用
ConcurrentMap
实现简单值的线程安全并发,该
ConcurrentMap
具有
集合
使用
生成的值

然后,要以原子方式获取每个值集,请使用:

同样,为了以线程安全的方式删除
Set
值持有者实例,您可以使用:


publicstaticvoidremove(最终ConcurrentMap不在JRE中。可能在Apache Commons等中。我检查了Apache注释,但找不到一个。有多值哈希映射,但它们不是线程安全的。可以使用ConcurrentHashMap,设置值。有什么观察结果吗?你不能使用简单同步吗?它必须是并发结构吗?@shmosel如果我使用synchronization在顶层它将阻止整个映射,然后就没有并发。我对此解决方案有两个问题。第一个问题是,通过同步添加-删除操作实现哈希表中的一个线程安全。它使整个哈希表在操作完成之前无法访问。相反,我可以使用concurrentHashMap。第二个问题是,我不能使用ConcurrentHashMap和ConcurrentHashSet放在一起。假设我要先向一个键添加一个值,我必须检查是否已经向该键添加了一个集。否则,我必须先添加该集,然后再添加该值。在这种情况下,另一个线程可能会覆盖该集。删除值时也会发生这种情况从集合中删除。当删除时,如果删除元素是集合中的最后一个元素,那么我们必须从HashMap中删除集合。如果一个线程向集合中添加值,而另一个线程删除集合,会发生什么情况?我建议添加您自己的同步包装器,它隐藏集合对象并仅获取集合值。类似于:class MyMap{private ConcurrentHashMap hm=…void put(K K,V V){synchronized(hm){ConcurrentHashSet hs=hm.get(K)if(hs==null){hs=new…}hs.add(V)}@Roberto Attias当put完成时,没有人可以访问映射,也没有必要使用ConcurrentHashMap。很抱歉:Hashtable很旧,并且使用了一种糟糕的并发策略(即禁止并发);它永远不应该用于非遗留代码。对于延迟的响应,很抱歉。我认为这是最好的方法。让我试试。
ConcurrentMap<String, Set<Integer>> multimap = new ConcurrentHashMap<>();
Set<Integer> fooValues = multimap.computeIfAbsent("foo", key -> Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>()));
ConcurrentMap<String, NavigableSet<Integer>> multimap = new ConcurrentHashMap<>();
NavigableSet<Integer> fooValues = multimap.computeIfAbsent("foo", key -> new ConcurrentSkipListSet<>());
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;
    });
}