Поскольку я читаю исходный код concurrentHashMap в java8, меня немного смущает переменная sizeCtl
, она говорит
При отрицательном значении таблица инициализируется или изменяется: -1 для инициализации, иначе - (1 + количество активных потоков с изменяющимся размером)
Но в исходном коде он будет использовать U.compareAndSetInt(this, SIZECTL, sc, sc + 1)
при попытке изменить размер ConcurrentHashMap
и использовать U.compareAndSetInt(this, SIZECTL, sc = sizeCtl, sc - 1)
после завершения операции.
Эти операции меня смущают, например, если одновременно происходит изменение размера карты двумя потоками, то sizeCtl
равно -3
, однако, когда новый поток пытается помочь изменить размер, sizeCtl
должно быть -4
в соответствии с описанием комментария выше, но, похоже, -2
в соответствии с кодом U.compareAndSetInt(this, SIZECTL, sc, sc + 1)
.
final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) {
Node<K,V>[] nextTab; int sc;
if (tab != null && (f instanceof ForwardingNode) &&
(nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
int rs = resizeStamp(tab.length);
while (nextTab == nextTable && table == tab &&
(sc = sizeCtl) < 0) {
if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
sc == rs + MAX_RESIZERS || transferIndex <= 0)
break;
if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) {
transfer(tab, nextTab);
break;
}
}
return nextTab;
}
return table;
}