作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下是 putVal
方法的部分代码:
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
if (tab == null || (n = tab.length) == 0)
tab = initTable(); // lazy Initialization
//step1,tabAt(...) is CAS
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
//step2,casTabAt(...) is CAS
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
break; // no lock when adding to empty bin
}
...
return null;
}
假设当前有两个线程,A
和B
,当A
执行step1
时,获取 true
,但同时 B
也执行 step1
并获取 true
。 A
和 B
都执行 step2
。
从这种情况来看,B
的Node
取代了A
的Node
,或者说A
的数据被B
替换,这是错误的。
不知道是对还是错,谁能帮我解决一下吗?
最佳答案
以下是 casTabAt
的实现方式:
static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,
Node<K,V> c, Node<K,V> v) {
return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
}
而U
声明如下:private static final sun.misc.Unsafe U;
。此类的方法在低级别保证原子性。从这个用法来看:
casTabAt(tab, i, null, new Node<K,V>(hash, key, value, null))
我们可以看到,assuming that the third parameter of compareAndSwapObject
is expected value, that ,由于保证了原子性,首先执行 compareAndSwapObject
的 A
或 B
线程将看到 null
这里和 compareAndSwapObject
实际上会替换对象,而下一个执行 compareAndSwapObject
的线程不会更改该值,因为 实际值不再为 null,而 null 被期望作为对值进行更改的条件。
关于java - 关于ConcurrentHashMap的putVal方法源代码的一个困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53536957/
我是一名优秀的程序员,十分优秀!