![](/img/trans.png)
[英]Java ConcurrentHashMap is better than HashMap performance wise?
[英]Java Concurrency: Are "get(Key) for HashMap and ConcurrentHashMap equal in performance?
当没有对底层Map进行修改时, get(Key)
方法调用标准HashMap
和ConcurrentHashMap
的性能相同(因此只执行get()操作。)
使用背景更新:
并发性是一个非常复杂的话题:我确实“并发/线程安全”,但只有看跌期权,这种情况极少发生。 对于看跌期权我可以交换地图关联本身(原子和线程安全)。 因此,我要求我做了很多获取(并且可以选择使用HashMap(创建临时Hashmap,将数据复制到新的HashMap,交换关联)或使用ConcurrentHashMap实现它...作为我的应用程序真的我想了解更多关于性能如何随着不同的获取而丢失。这听起来很愚蠢,互联网上有太多不必要的信息,但我觉得这可能会引起更多人的兴趣。所以,如果有人知道ConcurrentHashMap的内部工作原理,那么回答这个问题会很棒。
非常感谢!
你问的是错误的问题。
如果您需要并发性, 无论性能影响如何,都需要它。
一个正确行为的程序几乎总是比一个更快的程序排名更高。 我说“几乎总是”因为可能有商业原因要发布带有错误的软件,而不是在错误得到修复之前保留。
根据ConcurrentHashMap
API,检索方法没有锁定。 所以,我会说他们的表现相同。
你可以查看源代码。 (我正在看JDK 6)HashMap.get()非常简单:
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
其中hash()执行一些额外的移位和XORing以“改进”您的哈希码。
ConcurrentHashMap.get()有点复杂,但不是很多
public V get(Object key) {
int hash = hash(key.hashCode());
return segmentFor(hash).get(key, hash);
}
同样,hash()做了一些移位和异或。 setMentFor(int hash)执行简单的数组查找。 唯一复杂的东西是在Segment.get()中。 但即使这看起来不像火箭科学:
V get(Object key, int hash) {
if (count != 0) { // read-volatile
HashEntry<K,V> e = getFirst(hash);
while (e != null) {
if (e.hash == hash && key.equals(e.key)) {
V v = e.value;
if (v != null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}
获取锁定的一个地方是readValueUnderLock()。 评论说,这在内存模型下在技术上是合法的,但从未发生过。
总的来说,看起来两者的代码非常相似。 在ConcurrentHashMap中组织得更好一些。 所以我猜测性能足够相似。
也就是说,如果看跌非常罕见,您可以考虑实施“写入时复制”类型的机制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.