java - java8 中的 concurrentHashMap 中的 sizectl

标签 java concurrency concurrenthashmap

因为我正在阅读 java8 中 concurrentHashMap 的源代码,我对 sizeCtl 变量有点困惑,它说

When negative, the table is being initialized or resized: -1 for initialization, else -(1 + the number of active resizing threads)

但在源代码中,它会在尝试调整 ConcurrentHashMap 大小时使用 U.compareAndSetInt(this, SIZECTL, sc, sc + 1) 并使用 U.compareAndSetInt(this, SIZECTL, sc = sizeCtl, sc - 1) 完成运算后。

这些操作让我很困惑,例如,如果有 2 个线程同时调整 map 大小,那么 sizeCtl 就是 -3,但是,当一个new thread try to help resize, 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;
}

最佳答案

我以为它说错了。

When negative, the table is being initialized or resized: -1 for initialization, else -(1 + the number of active resizing threads)

自第一个进入函数的线程transfersizeCtl(resizeStamp(tab.length) << RESIZE_STAMP_SHIFT) + 2 .这是一个负值,它的绝对值非常大。这个sizeCtl在每个线程进入函数时加1,然后在每个线程退出函数前减1。

while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
               (n = tab.length) < MAXIMUM_CAPACITY) {
            int rs = resizeStamp(n);
            if (sc < 0) {
                if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
                    sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
                    transferIndex <= 0)
                    break;
                if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))
                    transfer(tab, nt);
            }
            else if (U.compareAndSwapInt(this, SIZECTL, sc,
                                         (rs << RESIZE_STAMP_SHIFT) + 2))
                transfer(tab, null);
            s = sumCount();
        }

这些是我的想法,但我不确定。

关于java - java8 中的 concurrentHashMap 中的 sizectl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52026232/

相关文章:

java,两个对象,object1 = object2 = class/type ...没看懂

java - 访问最终字段时出现奇怪的 NullPointerException

java - 如果写入的值始终相同,则延迟初始化引用是否是线程安全的?

使用 ConcurrentHashMap 和同步块(synchronized block)实现 Java 并发

java - 并发HashMap初始化

java - 输入一个单词然后在每个字母之间使用斜杠输出它们会导致错误

java - 异常重写方法

python - Tornado 中的队列和 ProcessPoolExecutor

java - 将消息传递给间接相关的参与者

C++ concurrent_unordered_map C++11 Microsoft 使用 unsigned long 作为 key/HASH 函数