并发 – JDK7中的ConcurrentHashMap代码说明(scanAndLockForPut)

JDK7中ConcurrentHashMap中方法scanAndLockForPut的
source codes说:

private HashEntry<K,V> scanAndLockForPut(K key, int hash, V value) {
    HashEntry<K,V> first = entryForHash(this, hash);
    HashEntry<K,V> e = first;
    HashEntry<K,V> node = null;
    int retries = -1; // negative while locating node
    while (!tryLock()) {
        HashEntry<K,V> f; // to recheck first below
        if (retries < 0) {
            if (e == null) {
                if (node == null) // speculatively create node
                    node = new HashEntry<K,V>(hash, key, value, null);
                retries = 0;
            }
            else if (key.equals(e.key))
                retries = 0;
            else
                e = e.next;
        }
        else if (++retries > MAX_SCAN_RETRIES) {
            lock();
            break;
        }
        else if ((retries & 1) == 0 &&
                 (f = entryForHash(this, hash)) != first) {
            e = first = f; // re-traverse if entry changed
            retries = -1;
        }
    }
    return node;
}

我理解代码的含义,但如果输入代码,我不知道的是其他内容:

else if ((retries & 1) == 0 && (f = entryForHash(this, hash)) != first)

我的问题是:
为什么我们要做“(重试& 1)== 0”?

编辑:
我有点想通了.这都是因为常量MAX_SCAN_RETRIES:

static final int MAX_SCAN_RETRIES = Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1;

在单核处理器中,MAX_SCAN_RETRIES = 1.因此第二次线程进入循环“while(tryLock)”时,不必检查第一个节点是否已更改.

但是,在多核处理器中,这将像检查第一个节点是否在while循环中每2次更改一样.

以上解释是否正确?

最佳答案 让我们打破这个:

1:

(retries & 1) == 0

这对于奇数返回1,对于偶数返回0.基本上,要想过去,如果数字是偶数的话,那就有1比2的机会.

2:

f = entryForHash(this, hash)

f是一个临时变量,用于存储段中最新条目的值.

3:

(/* ... */) != first

检查值是否更改.如果是,则将当前条目移动到开始,并再次重新迭代链接的节点以尝试获取锁定.

点赞