我一直在研究编写并发Multimap的问题,我有一个由Google Guava AbstractSetMultimap和MapMaker计算映射支持的实现,它根据需要创建值集合作为在ConcurrentHashMap上设置视图。有些关注视图集和各种包装器,我认为这非常接近。
discussed others have试过这个问题已经the discussion here的大问题,似乎是当底层地图变空时将其删除,没有引入竞争条件。
似乎存在两种选择。
问题:
由于
编辑:另请参阅guava邮件列表中的this Google code area。
编辑2:我已经写完了。有关实施,请参阅{{3}}。我非常感谢任何尝试它的人的反馈,而不是在这里。
答案 0 :(得分:1)
我之前提出了同样的问题,最终实现了4种不同的实现。
问题: High-performance Concurrent MultiMap Java/Scala
impl(我称之为索引) http://github.com/jboner/akka/blob/master/akka-actor/src/main/scala/actor/ActorRegistry.scala#L314
答案 1 :(得分:0)
如果你真的不想泄漏空集合,你可以尝试用每个键占位符Future原子地替换它。这样,并发添加/删除或添加/添加应该能够在再次扩展时达到一致状态。
答案 2 :(得分:0)
使用不可变集合作为值是解决/简化基本并发问题的最佳方法,然后可以使用原子替换方法进行删除。不幸的是,通常使用的快速复制/更新配置文件不具有不可变集合,因此您通常需要进行相当昂贵的复制。
答案 3 :(得分:0)
作为后续内容,以下是我之前讨论中遗漏的一些细节,这些讨论是关于我的并发多图实现的。
该实现遵循了您的第一个建议:在支持映射中留下空集合。以下实时视图行为会使您的其他建议变得复杂。
Multimap<String, Integer> multimap = HashMultimap.create();
Set<Integer> set = multimap.get("foo");
multimap.put("foo", 1);
int count = set.size(); // equals 1
对于真实世界的应用程序而言,与集合库类相反,少于完全并发的多重映射的东西可能就足够了。您可以定义自己的类,该类实现Multimap接口的子集或有限的并发保证选择。或者,您的应用程序逻辑可以最小化同步多图的争用,以避免性能问题。