use*_*216 5 java concurrency map
当底层 Map 没有发生任何修改时,get(Key)方法调用是否符合标准HashMap和ConcurrentHashMap性能相同(因此只执行 get() 操作。)
更新背景:
并发是一个相当复杂的话题:我确实需要“并发/线程安全”,但只在看跌期权上,这种情况很少发生。对于 puts,我可以交换 Map Associations 本身(这是原子和线程安全的)。因此我问我正在做很多获取(并且可以选择使用 HashMap 实现它(创建一个临时 Hashmap,将数据复制到新的 HashMap,并交换关联)或使用 ConcurrentHashMap ......就像我的应用程序一样doeas很多gets我想更多地了解两种不同gets的性能如何损失。这听起来很愚蠢,但互联网上有太多不必要的信息,但我认为这是更多人可能感兴趣的东西。所以如果有人知道 ConcurrentHashMap 的内部工作原理,回答这个问题会很棒。
非常感谢!
你可以看一下源代码。(我正在查看 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;
}
Run Code Online (Sandbox Code Playgroud)
hash() 会进行一些额外的移位和异或来“改进”您的哈希代码。
ConcurrentHashMap.get() 稍微复杂一点,但也不是很多
public V get(Object key) {
int hash = hash(key.hashCode());
return segmentFor(hash).get(key, hash);
}
Run Code Online (Sandbox Code Playgroud)
同样,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;
}
Run Code Online (Sandbox Code Playgroud)
获得锁的一个地方是 readValueUnderLock()。评论称,这在内存模型下技术上是合法的,但从未发生过。
总的来说,看起来两者的代码非常相似。在 ConcurrentHashMap 中组织得更好一些。所以我猜性能足够相似。
也就是说,如果看跌期权确实非常罕见,您可以考虑实现“写时复制”类型的机制。
| 归档时间: |
|
| 查看次数: |
957 次 |
| 最近记录: |