我想知道ConcurrentHashMap
上调用的size()
方法是否与通常的HashMap的size()
方法具有相同的复杂度。并发hashmap大小()方法复杂度
回答
它不是。在我的版本的JDK,HashMap.size()
有O(1)
的复杂性,而ConcurrentHashMap.size()
在最好的情况下有遍历段。在最糟糕的情况下,它会锁定所有细分市场,在多线程场景中这可能是一项非常昂贵的操作。
当然,这是更快的的是一个不同的问题完全。答案在很大程度上取决于有多少线程访问地图,以及他们正在做什么。
size()
的上HashMap
的复杂性是O(1)
,由于尺寸被存储在字段。如果我们看一下size()
上ConcurrentHashMap
实施,我们看到,这是更大(> O(1))
参考(OpenJDK的-6)
中的ConcurrentHashMap大小()方法的复杂性本质上是一个O(N)的操作(主要是改变与段的数量),其可以在故见urce。 HashMap是一个O(1)操作。
/**
* Returns the number of key-value mappings in this map. If the
* map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* @return the number of key-value mappings in this map
*/
public int size() {
final Segment<K,V>[] segments = this.segments;
long sum = 0;
long check = 0;
int[] mc = new int[segments.length];
// Try a few times to get accurate count. On failure due to
// continuous async changes in table, resort to locking.
for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
check = 0;
sum = 0;
int mcsum = 0;
for (int i = 0; i < segments.length; ++i) {
sum += segments[i].count;
mcsum += mc[i] = segments[i].modCount;
}
if (mcsum != 0) {
for (int i = 0; i < segments.length; ++i) {
check += segments[i].count;
if (mc[i] != segments[i].modCount) {
check = -1; // force retry
break;
}
}
}
if (check == sum)
break;
}
if (check != sum) { // Resort to locking all segments
sum = 0;
for (int i = 0; i < segments.length; ++i)
segments[i].lock();
for (int i = 0; i < segments.length; ++i)
sum += segments[i].count;
for (int i = 0; i < segments.length; ++i)
segments[i].unlock();
}
if (sum > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
else
return (int)sum;
}
这并没有真正的帮助。您能否移除冗长的源代码片段,而是告诉我们为什么地图会分成多个片段,以及我们可以找到多少片段?只有当分段的数量是N的恒定分数时,我们才会得到O(N)复杂度。 –
这是因为在同时可变结构调用大小()本质上是一个毫无意义的事情做一个不相干的问题。所有它会告诉你的是的大小是,除了可能记录它之外,你实际上不能对这些信息做任何事情。
如果你尝试和使用大小()没有锁定,您将有竞争条件的结构。
在JDK 8新实现的ConcurrentHashMap.size()使用冷却算法他们那种从复制粘贴LongAdder。
实际上,ConcurrentHashMap.size()
的复杂度几乎是恒定的(nerd语言中的“O(1)”),并且与HashMap.size()
相比的实时成本可以忽略不计。不要相信我?打开我的基本test project并自己跑步。我目前的机器上没有安装JDK 7,与Java 1.8相比,使用Java 1.7获得关于时间成本的反馈会很酷。
有趣的发现,马丁! – kgdinesh
- 1. 并发HashMap:检查大小
- 2. 复杂的Hashmap ArrayList的发电机
- 3. 算法复杂度大O,小O,大欧米茄,小欧米茄,西塔
- 4. 最小复杂度的字谜算法
- 5. 算法复杂度与输入固定大小
- 6. 算法复杂度和大O符号
- 7. 算法的大O复杂度
- 8. 合并排序时间复杂度与我的算法。大O
- 9. 非大O复杂度
- 10. 大O时间复杂度
- 11. 大-θ,时间复杂度
- 12. 确定.NET中复杂对象大小的方法?
- 13. extjs时间复杂度的Store.load方法
- 14. hashmap删除复杂性
- 15. 操纵复杂的HashMap
- 16. 获取HashMap中值的大小/长度
- 17. Dijkstra的算法 - 复杂度
- 18. NSGA ii算法复杂度
- 19. 算法复杂度时间
- 20. 2^n复杂度算法
- 21. 算法分析(复杂度)
- 22. LZ复杂度算法
- 23. Hash Map调整大小的时间复杂度
- 24. 时间复杂度,以获得最大的堆最小元素
- 25. O(n)复杂度子段中最大值的最小值...
- 26. Java并发HashMap
- 27. 最小生成树时间复杂度
- 28. 最坏情况复杂度与输入大小成反比的算法?
- 29. 复杂的Windows桌面大小增加
- 30. 算法复查时间复杂度
我发现,在JDK 8,这不再是真实的。在此页面的其他位置查看我的答案(或[单击此处](http://stackoverflow.com/a/22996395/1268003))。 –