我正试图了解ConcurrentHashMap中的锁是如何工作的。我的理解是,在ConcurrentHashMap中有段,写请求获取特定段的锁,而在其他段上可以同时读取。但是说,
发布于 2021-02-17 14:07:15
理解ConcurrentHashMap的最佳方法是在查看源代码时理解java中的同步。来自源代码http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/concurrent/ConcurrentHashMap.java
对空bin中的第一个节点执行
插入(通过+[]=+或其变体),只需将其插入到bin。到目前为止,这是在大多数key/hash发行版下进行put操作的最常见情况。其他更新操作(插入、删除和替换)需要锁。我们不想浪费将一个单独的锁对象与每个bin相关联所需的空间,所以使用bin列表本身的第一个节点作为锁。对这些锁的阻塞支持依赖于+
Util::CheapLockable。但是,我们还需要一个try_lock结构,因此我们使用节点哈希字段的位来控制锁(参见上文),因此通常只使用内置监视器来使用cheap_wait/cheap_broadcast结构来阻塞和发送信令。见+Node#try_await_lock+。对这些锁的锁定支持依赖于内置的“同步”监视器。这意味着
这基本上意味着ConcurrentHashMap上的每个插入/更新/删除操作都会被阻塞,直到操作完成为止。
对于读取值,不存在阻塞。
public V get(Object key) {
Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;
int h = spread(key.hashCode());
if ((tab = table) != null && (n = tab.length) > 0 &&
(e = tabAt(tab, (n - 1) & h)) != null) {
if ((eh = e.hash) == h) {
if ((ek = e.key) == key || (ek != null && key.equals(ek)))
return e.val;
}
else if (eh < 0)
return (p = e.find(h, key)) != null ? p.val : null;
while ((e = e.next) != null) {
if (e.hash == h &&
((ek = e.key) == key || (ek != null && key.equals(ek))))
return e.val;
}
}
return null;
}https://stackoverflow.com/questions/66242664
复制相似问题