В ArrayBlockingQueue зачем копировать конечное поле участника в локальную конечную переменную?

В ArrayBlockingQueue все методы, которые требуют блокировки, копируют его в локальную final переменную перед вызовом lock() .

 public boolean offer(E e) { if (e == null) throw new NullPointerException(); final ReentrantLock lock = this.lock; lock.lock(); try { if (count == items.length) return false; else { insert(e); return true; } } finally { lock.unlock(); } } 

Есть ли причина для копирования this.lock в локальную lock переменных, когда поле this.lock является final ?

Кроме того, он также использует локальную копию E[] прежде чем действовать на нее:

 private E extract() { final E[] items = this.items; E x = items[takeIndex]; items[takeIndex] = null; takeIndex = inc(takeIndex); --count; notFull.signal(); return x; } 

Есть ли причина для копирования конечного поля в локальную конечную переменную?

Это экстремальная оптимизация Doug Lea, автор classа, любит использовать. Вот сообщение в недавнем streamе в списке рассылки core-libs-dev об этом точном вопросе, который хорошо отвечает на ваш вопрос.

с поста:

… копирование на местный язык производит наименьший байт-код, а для низкоуровневого кода приятно писать код, который немного ближе к машине

Этот stream дает ответы. По существу:

  • компилятор не может легко доказать, что конечное поле не изменяется в рамках метода (из-за отражения / сериализации и т. д.),
  • большинство современных компиляторов на самом деле не пытаются и поэтому должны перезагружать конечное поле каждый раз, когда оно используется, что может привести к промаху в кеше или ошибке страницы
  • сохранение его в локальной переменной заставляет JVM выполнять только одну нагрузку
  • Разница в скорости при использовании встроенных строк против конкатенации в php5?
  • Помощь оптимизации цикла цикла для окончательного назначения
  • Анимированная анимация Swing
  • Лучше ли использовать std :: memcpy () или std :: copy () в терминах производительности?
  • Смотрите и очистите кеши / буферы Postgres?
  • Поиск ближайшего соседа с использованием оптимизированного алгоритма Левенштейна
  • Java Integer compareTo () - зачем использовать сравнение или вычитание?
  • Оказывание программы для конвейера в процессорах Intel Sandybridge
  • Почему лямбды лучше оптимизируются компилятором, чем простые функции?
  • Что случилось с использованием ассоциативности компиляторами?
  • Как я могу ранжировать наблюдения в группе быстрее?
  • Давайте будем гением компьютера.