Since I am reading the source code of the concurrentHashMap in java8, I am a little confused about the sizeCtl variable, it says
When negative, the table is being initialized or resized: -1 for initialization, else -(1 + the number of active resizing threads)
But in the source code, it will use U.compareAndSetInt(this, SIZECTL, sc, sc + 1) when trying to resize the ConcurrentHashMap and use U.compareAndSetInt(this, SIZECTL, sc = sizeCtl, sc - 1) after finishing the operation.
These operations confuse me, for example, if there is 2 thread resize the map at the same time, then the sizeCtl is is -3, however, when a new thread try to help resize, the sizeCtl should be -4 according to the description of the comment above, but it seems to be -2 according to the code 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;
}