Зачем назначать конечную переменную поля локальной копии перед вызовом ее метода (Best Practice или по определенной причине)?

При проверке исходного кода ArrayBlockingQueue я заметил, что перед вызовом любого метода экземпляра объекта конечное поле было назначено локальной переменной. Это делается для достижения определенной цели?

public E peek() {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        return (count == 0) ? null : items[takeIndex];
    } finally {
        lock.unlock();
    }
}

Ответы

Ответ 1

Здесь обсуждается . В основном это оптимизация, позволяющая более быстрый доступ к блокировке. Несмотря на то, что this.lock является окончательным, jvm по-прежнему выполняет поиск по полю каждый раз, когда этот доступ к элементу доступен, делая окончательную копию, он немного быстрее.

Ответ 2

Код использует этот шаблон, потому что он хочет разрешить изменение поля this.lock.

Предположим, что два потока обращаются к объекту ArrayBlockingQueue. Один из них запускает метод peek(), а другой изменяет блокировку.

Если код peek() не зафиксировал исходное значение this.lock в локальной переменной lock, тогда он вызвал бы unlock (наконец, закрыть) в недавно назначенной блокировке, где as его нужно вызвать в оригинальной блокировке.

(Это отличное объяснение, но, к сожалению, оно не относится к классу ArrayBlockingQueue, так как поле lock является окончательным).