通常(即不同时),putAll()
不能比使用批次调用put()
更有效,即使假设您排除了构建传递给{{的其他地图的成本1}}。那是因为putAll()
将需要迭代传递的Map的元素,并运行算法以将每个键值对添加到putAll()
执行的Map。
但对于ConcurrentHashMap,构建常规Map然后使用put()
更新它是否有意义?或者我应该只对putAll()
进行10(或100或1000)次呼叫?
对put()
的多次调用,答案是否会改变?
谢谢!
答案 0 :(得分:3)
Java Collections中的第一个(主要是)线程安全映射是使用HashMap
的同步Collections.synchronizedMap()
。它的工作原理是一次只允许一个操作。 Java 5添加了ConcurrentHashMap
,其工作方式不同。基本上Map
被分成片。 put()
操作仅锁定相关切片。它还添加了线程安全原语,如putIfAbsent()
。
我解释这一点的原因是putAll()
可能或多或少有效,具体取决于它的实现方式。它可以通过锁定整个映射来工作,这实际上可能比尝试在每个put()
上获取单独的锁更有效。或者它可以通过做一堆put()
调用来工作,在这种情况下没有太大区别。
因此,如果它对您的代码有意义并且您同时进行了大量更新,我会使用putAll()
,除非您正在追踪putIfAbsent()
。
编辑:我刚检查过,Java 6 ConcurrentHashMap
实现了putAll()
作为put()
操作的循环,所以这比自己做的更好或更糟
答案 1 :(得分:2)
putAll()
只是代表put()
。如果您还没有中间地图,则无需建立中间地图。您可以在源代码中看到这一点,并且您使用的Java实现并不重要,因为代码是公共域并由所有代码共享。
请注意putAll()
不是原子的,而只是保证每个put()
都是原子的。