'scanAndLockForPut' в ConcurrentHashMap JDK1.7

Мой вопрос касается предложения в документе:

В отличие от большинства методов, вызовы методов equals не проверяются: поскольку скорость обхода не имеет значения, мы могли бы также помочь разогреть связанный код и доступы.

Я не могу понять приведенную выше фразу. В частности, что означает «не проверено»? И почему мы можем «подогреть связанный код»?

scanAndLockForPut

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;

person chain ro    schedule 29.07.2015    source источник
comment
Я думаю, что, поскольку время удержания блокировки короткое, он пытается разогреть кэши во время ожидания вместо блокировки и, возможно, происходит переключение контекста.   -  person Ben Manes    schedule 29.07.2015


Ответы (1)


В частности, что означает «не проверено»?

В этом контексте «экранированный» означает проверку личности перед вызовом равенства. Левая часть следующего утверждения также взята из CHM:

if ((k = e.key) == key || (e.hash == hash && key.equals(k)))

Следовательно, «не проверено» означает пропуск проверки личности.

И зачем нам «разогревать связанный код»?

Положите и получите, используйте метод equals для ключа, чтобы определить совпадение, а в случае прогрева, что более важно, чтобы определить, что не соответствует, что всегда будет вызовом equals, даже если вы проверяете личность. Если все ожидающие потоки начнут вызывать key.equals, это сделает его «горячим» и вызовет JIT-компиляцию раньше. Более быстрый метод equals означает меньшее время удерживания блокировки сегмента во время пута.

Также важно отметить, что в JDK 8 все это было изменено.

person jmehrens    schedule 08.03.2016