【发布时间】:2021-11-18 14:05:21
【问题描述】:
我正在学习java源代码,当我阅读ConcurrentHashMap源代码时,我对initTable()方法感到困惑,为什么要检查(tab = table) == null || tab.length == 0两次,首先是while(),然后是@987654323 @。我无法想象在什么情况下需要第二次检查。
我想可能是因为 JVM 重新排序了代码,把 sizeCtl = sc; 放在了 Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n]; 前面。这只是我的猜测,我不知道是否正确。
谁能解释一下,非常感谢。
private final Node<K,V>[] initTable() {
Node<K,V>[] tab; int sc;
while ((tab = table) == null || tab.length == 0) {
if ((sc = sizeCtl) < 0)
Thread.yield(); // lost initialization race; just spin
else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
try {
if ((tab = table) == null || tab.length == 0) {
int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
@SuppressWarnings("unchecked")
Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
table = tab = nt;
sc = n - (n >>> 2);
}
} finally {
sizeCtl = sc;
}
break;
}
}
return tab;
}
【问题讨论】: