gpt4 book ai didi

java - ConcurrentHashMap.get() 如何防止脏读?

转载 作者:行者123 更新时间:2023-12-04 04:57:43 25 4
gpt4 key购买 nike

我正在查看 ConcurrentHashMap 的源代码并想知道如何 get()方法在没有任何监视器的情况下工作,这是代码:

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))) // mark here for possible dirty read
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)))) // mark here for possible dirty read
return e.val;
}
}
return null;
}

我标记的两行做同样的事情:检查 key当前的 Node<K, V>等于 key需要。如果true , 将返回其对应的值。但是,如果另一个线程在 return 之前插入怎么办?和 remove()这个节点来自数据结构。由于局部变量e仍然持有已删除节点的引用,GC 将保留它并且 get()方法仍将返回已删除的值,从而导致脏读。

我错过了什么吗?

最佳答案

It doesn't :

Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations holding upon their onset. (More formally, an update operation for a given key bears a happens-before relation with any (non-null) retrieval for that key reporting the updated value.)

这通常不是问题,因为 get 永远不会返回如果 get 方法获得锁就不会发生的结果,从而阻止更新操作另一个线程。您得到的结果就好像 get 调用发生在更新操作开始之前一样。

因此,如果您不介意 get 发生在更新之前还是之后,您也不应该介意它发生在更新期间,因为有期间之前之间没有可观察到的差异。如果您确实希望 get 似乎发生在更新之后,那么您将需要从更新线程发出更新已完成的信号;等待获取锁无论如何都不会实现这一点,因为您可能会在更新发生之前获得锁(在这种情况下,您会得到与没有获取锁相同的结果)。

关于java - ConcurrentHashMap.get() 如何防止脏读?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60284815/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com