Может ли кто-нибудь объяснить, почему мы используем final AtomicInteger count = this.count; и почему используем ключевое слово final [duplicate]

public E poll() {
    final AtomicInteger count = this.count;
    if (count.get() == 0)
        return null;
    E x = null;
    int c = -1;
    final ReentrantLock takeLock = this.takeLock;
    takeLock.lock();
    try {
        if (count.get() > 0) {
            x = dequeue();
            c = count.getAndDecrement();
            if (c > 1)
                notEmpty.signal();
        }
    } finally {
        takeLock.unlock();
    }
    if (c == capacity)
        signalNotFull();
    return x;
}

Может ли кто-нибудь объяснить, почему мы назначаем this.count локальной переменной, а также почему локальная переменная объявлена ​​как final?


person Haifeng Zhang    schedule 23.10.2013    source источник
comment
@assylias volatile объяснение имеет (некоторый) смысл в отношении AtomicInteger - не в отношении ReentrantLock.   -  person Nir Alfasi    schedule 23.10.2013
comment
@assylias далее, что касается AtomicInteger: в этом случае автор мог бы просто использовать count.get() в начале метода и работать с int.   -  person Nir Alfasi    schedule 23.10.2013
comment
@assylias, который оставляет только объяснение, что если переменная объявлена ​​final, есть более высокая вероятность того, что локальная переменная в конечном итоге будет привязана к регистру процессора   -  person Nir Alfasi    schedule 23.10.2013
comment
@alfasin да вот что это такое. Хотя есть еще один параметр: оптимизировать конечные поля не так просто для компилятора - в частности, из-за отражения конечное поле может измениться. Локальная переменная не может. В результате некоторые оптимизации компилятора доступны для локальных переменных, но не для конечных полей.   -  person assylias    schedule 24.10.2013


Ответы (3)


Единственная ценность, которую я вижу в таких вещах, как:

final AtomicInteger count = this.count;

а также:

final ReentrantLock takeLock = this.takeLock;

это: в случае, если исходный член не был объявлен как final, и автор хотел сигнализировать программистам, которые будут поддерживать этот код в будущем - ни в коем случае не изменять ссылку на эти объекты (что достигается final декларация).

ОБНОВЛЕНИЕ:
Этот код взят из реализации LinkedBlockingQueue, написанный Дугом Ли. Согласно ссылке, которая размещена выше, Марко написал:

Кроме того, даже когда рассматриваемая переменная-член не является изменчивой, но окончательной, эта идиома имеет отношение к кэшам ЦП, поскольку чтение из местоположения стека более удобно для кеширования, чем чтение из случайного местоположения кучи. Также существует более высокая вероятность того, что локальная переменная будет связана с регистром ЦП.

В отношении этого последнего случая на самом деле есть некоторые разногласия, поскольку компилятор JIT обычно позаботится об этих проблемах, но Дуг Ли - один из тех, кто придерживается этого из общих принципов.

person Nir Alfasi    schedule 23.10.2013
comment
Я думаю, что этот фрагмент взят из самого jdk, и неопытный писатель является основным участником параллельного API ... Я бы не стал ставить на него, что он не знает, что он делает ... - person assylias; 23.10.2013
comment

Может ли кто-нибудь объяснить, почему мы присваиваем this.count локальной переменной

Это может потенциально улучшить производительность, поскольку доступ к локальной переменной немного дешевле, чем доступ к переменной экземпляра. Этот пост, кажется, поддерживает это. Однако они также говорят, что это крайняя оптимизация, которая может не понадобиться.

а также почему локальная переменная объявлена ​​как final?

Кажется, что поле count определяется как final в исходный код. Они могут просто захотеть согласоваться, объявив локальную переменную как final.

person Terry Li    schedule 23.10.2013

Я уверен, что это связано с различными оптимизациями компилятора. В общем, подсказки компилятора, подобные этому, не нужны, поскольку компилятор теоретически должен быть в состоянии вычислить эту конкретную оптимизацию самостоятельно, но авторы JDK, вероятно, лучше осведомлены о фактической практической реализации компилятора и, следовательно, знают, что это создаст более быстрый байт-код.

person LadyCailin    schedule 23.10.2013