Зачем назначать конечную переменную поля локальной копии перед вызовом ее метода (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
является окончательным).