java - 并发多重映射放置和删除

标签 java data-structures concurrency synchronization multimap

这是一个组合并发列表多重映射实现。较低级别的实现会更好,但也更复杂。

忽略子列表中的 O(n) 删除,这是将 ConcurrentMap 和 CopyOnWriteArrayList 组合成功能性 ConcurrentMultimap 的正确方法吗?是否有任何 Unresolved 数据竞争?

private final ConcurrentMap<K, Collection<V>> map = ...; // inconsequential

public boolean put(K key, V value) {
 Collection<V> list = map.get(key);
 if(list != null) {
   list.add(value);
   return true;
 }

 // put if absent double check to avoid extra list creation
 list = new CopyOnWriteArrayList<V>();
 list.add(value);
 Collection<V> old = map.putIfAbsent(key,value);
 if(old != null) old.add(value);
 return true;
}

public boolean remove(Object key, Object value) {
 Collection<V> list = map.get(key);
 if(list == null) return false;

 // O(n) remove is the least of my worries
 if( ! list.remove(value)) return false;

 if( ! list.isEmpty()) return true;

 // double-check remove
 if( ! map.remove(key,list)) return true; // already removed! (yikes)

 if(list.isEmpty()) return true;

 // another entry was added!
 Collection<V> old = map.putIfAbsent(key,list);

 if(old == null) return true;

 // new list added!
 old.addAll(list);
 return true;
}

最佳答案

我认为你有一场比赛。我看到的问题是“put”中的线程无法确保插入的列表未被删除和/或替换为另一个列表。

观察:

线程 1 调用 put(),并检索(或创建)与该键关联的列表。同时,线程 2 从映射中删除该列表。数据丢失。

我认为您需要添加一个重试循环来验证添加到 map 后正确的列表是否位于 map 中。

关于java - 并发多重映射放置和删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/985012/

相关文章:

java - 如何在多树中找到最大的公共(public)子树

检查 C 字典中的单词

performance - Scala 中的并发处理

java - 对学习 Java 并发的程序或小项目有什么建议吗?

java - 等待如何知道Java中的中断?

java - 如何通过使用 Selenium Grid 将文件从本地计算机传输到远程 Web 服务器来上传文件

data-structures - 为什么在红黑树上使用堆?

java - 奇怪的错误 - 如何暂停 java 程序?

java - 需要知道每个字段是否已更改,我应该如何在 Hibernate 中对其进行建模

java - 使用子类引用创建父类的实例