在正常情况下(即,不是同时执行的),即使假定您排除了构建传递给putAll()
的另一个Map的成本,put()
也不会比使用大量putAll()
调用效率更高。这是因为putAll()
将需要迭代传递的Map的元素,并需要执行将每个键值对添加到put()
执行的Map的算法。
但是对于ConcurrentHashMap,构造常规Map然后使用putAll()
更新它是否有意义?还是我应该对put()
进行10次(或100次或1000次)调用?
多次呼叫putIfAbsent()
时,答案是否改变?
谢谢!
最佳答案
Java集合中的第一个(主要是)线程安全映射是使用HashMap
同步的Collections.synchronizedMap()
。它一次只能执行一项操作。 Java 5添加了ConcurrentHashMap
,其工作原理有所不同。基本上Map
分为多个切片。 put()
操作将仅锁定相关片。它还添加了诸如putIfAbsent()
之类的线程安全原语。
我之所以这样解释,是因为putAll()
的效率可能有所不同,具体取决于其实现方式。它可以通过锁定整个映射来工作,实际上,这可能比尝试在每个put()
上获取单独的锁定更为有效。或者也可以通过执行一堆put()
调用来工作,在这种情况下,差别不大。
因此,如果对您的代码有意义并且您一次要进行大量更新,那么除非您要使用putAll()
,否则我将使用putIfAbsent()
。
编辑:我刚刚检查过,Java 6 ConcurrentHashMap
将putAll()
实现为put()
操作的循环,因此它并不比自己做的更好或更糟。