你可以看看源代码。 (我期待在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;
}
凡散列()做一些额外的转换和异或“改善”的哈希码。
ConcurrentHashMap.get()是更复杂一些,但不是很多
public V get(Object key) {
int hash = hash(key.hashCode());
return segmentFor(hash).get(key, 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中组织好一点。所以我猜测性能足够相似。
这就是说,如果真的是非常罕见的,你可以考虑实现一个“复制写入”类型的机制。
ConcurrentHashMap是线程安全的。这伴随着每一项操作的开销。但是,除非您的应用程序花费90%的时间从中检索值,否则您不会注意到其中的差异。 – bdares 2012-01-29 03:29:59
你好,为什么我会得到一个downvote?请解释为什么! – user1145216 2012-01-29 03:30:02
你看看API吗?它清楚地表明写入是同步的,而检索不是。还有什么要知道的? – blackcompe 2012-01-29 06:34:51