1

通常(即非同时),即使假设您排除了构建传递给的另一个 Map 的成本,putAll()也不会比使用大量调用更有效。那是因为将需要迭代传递的 Map 的元素,以及运行将每个键值对添加到执行的 Map 的算法。put()putAll()putAll()put()

putAll()但是对于一个 ConcurrentHashMap 来说,构造一个常规的 Map 然后用它来更新它有意义吗?还是我应该只打 10 次(或 100 次或 1000 次)电话put()

多次调用的答案是否会改变putIfAbsent()

谢谢!

4

2 回答 2

4

Java Collections 中的第一个(主要是)线程安全 Map 是HashMap使用Collections.synchronizedMap(). 它的工作原理是一次只允许一项操作。Java 5 添加了ConcurrentHashMap,它的工作方式不同。基本上Map分为片。一个put()操作只会锁定相关的切片。它还添加了线程安全原语,例如putIfAbsent().

我解释这一点的原因是,这putAll()可能或多或少取决于它的实施方式。它可以通过锁定整个地图来工作,这实际上可能比尝试在每个put(). 或者它可能通过调用一堆电话来工作put(),在这种情况下没有太大区别。

因此,如果它对您的代码有意义并且您同时进行大量更新,那么我会使用它,putAll()除非它putIfAbsent()是您所追求的。

编辑:我刚刚检查过,Java 6ConcurrentHashMap实现putAll()为一个put()操作循环,所以它没有比自己做这件事更好或更差。

于 2009-11-05T02:22:39.187 回答
2

putAll()只是代表put(). 如果您还没有中间地图,则无需构建中间地图。您可以在源代码中看到这一点,您使用什么 Java 实现并不重要,因为代码是公共领域的并且由所有人共享。

请注意,这putAll()不是原子的,而只是保证每个个体put()都是原子的。

于 2009-11-05T18:07:06.027 回答