为什么Java没有提供CopyOnWriteMap?

45

JDK内置了CopyOnWrite*实现,用于实现SetList,但没有为Map提供,我经常对此感到遗憾。我知道还有其他的集合实现具有这些功能,但如果标准库中也提供这一功能就太好了。这似乎是一个明显的缺失,我想知道是否有充分的理由。有人知道为什么会被忽略吗?


4
很多人认为java.util.Map是一个集合,但实际上它并不是。这与你的问题没有直接关系,但是我认为你可能会有这样的假设,所以我想指出这一点。 - pkaeding
1
同意,它可能没有实现Collection接口,我们可以争论真正的集合是什么语义。但是这种细微之处的结果不会使CopyOnWriteMap变得不那么有价值或缺失。 - sgargan
迭代对于映射而言并不像其他集合类型那样常见。 - clstrfsck
2
如果您正在寻找高性能的CopyOnWriteMap,我们在这里提供了一个实现:https://labs.atlassian.com/wiki/display/CONCURRENT/CopyOnWriteMap - Jed Wesley-Smith
@JedWesley-Smith,那个链接需要登录才能访问。 - Erik van Oosten
1
@ErikvanOosten 谢谢,代码已经迁移到 Bitbucket:https://bitbucket.org/atlassian/atlassian-util-concurrent/wiki/CopyOnWrite%20Maps - Jed Wesley-Smith
2个回答

36

我猜这取决于你的用例,但是既然你已经有了ConcurrentHashMap,为什么还需要CopyOnWriteMap呢?

对于只有一个或少数更新操作,但有很多读取操作的简单查找表而言,它非常适合。

相对于写入时复制集合:

读取并发性:

等同于写入时复制集合。几个读者可以以无锁方式同时从地图中检索元素。

写入并发性:

比写入时复制集合更好的并发性,后者基本上会将更新序列化(一次一个更新)。如果你的哈希键均匀分布,使用并发哈希映射你就有很好的机会同时进行多个更新。

如果你想要实现CopyOnWriteMap的效果,可以始终使用并发级别为1的ConcurrentHashMap进行初始化。


1
请再次阅读ConcurrentHashMap的javadoc,我认为它非常适合您的需求。以下是其中两个片段:“支持完全并发检索的哈希表…”和“…所有操作都是线程安全的,检索操作不需要锁定…”。所以,是的,它非常适合作为一个并发查找表。 - Fredrik Bromee
7
在我们的测试中,我们发现使用底层j.u.HashMap实现的CopyOnWriteMap在读取方面优于ConcurrentHashMap。我们将它用于读多写少(例如配置)性能关键的区域。https://labs.atlassian.com/wiki/display/CONCURRENT/CopyOnWriteMap - Jed Wesley-Smith
3
由于某种原因,他们决定将这些重定向到内部信息页面而不是 bitbucket 上实际目标的位置:https://bitbucket.org/atlassian/atlassian-util-concurrent/wiki/CopyOnWrite%20Maps。 - Jed Wesley-Smith
2
使用copyOnWrite并不完全等同于ConcurrentHashMap。例如,在我的情况下,我想要获取地图当前视图的快照,并且我不希望我的读取被某些“写入”阻塞。我真的不关心任何新数据,我想要在进行第一次“put”时获得地图的一致视图。 - egelev
3
如果你需要在一个线程中遍历整个 map,而另一个线程正在执行 put 操作,那么了解迭代过程中不会在中途抛出 ConcurrentModificationException 异常是很好的。 - Jayen
显示剩余11条评论

-3

实现一个集合最简单的方法通常是使用底层的映射。它们甚至有一个 Collections.newSetFromMap() 方法[可能只在1.6版本以上可用]。

他们应该做的是有一个CopyOnWriteMap和CopyOnWriteSet,它们相当于Collections.newSetFromMap(new CopyOnWriteMap())。

但是正如你所看到的CopyOnWriteArraySet实际上是由数组而不是映射支持的。对于您的用例,Collections.newSetFromMap(ConcurrentHashMap())是否可接受?


OP要求的是地图而不是集合。 - eckes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接