Вот часть кодов для 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
's данные заменены на B
, это неправильно.
Я не знаю, правильно это или неправильно, кто-нибудь может мне помочь решить это?