Search code examples
javamethodsfinalatomicinteger

Can anyone explain why we use "final AtomicInteger count = this.count;", and why use keyword final


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;
}

Can anyone explain why we assign this.count to a local variable, and also why the local variable declared as final?


Solution

  • The only value I can see in doing things like:

    final AtomicInteger count = this.count;
    

    and:

    final ReentrantLock takeLock = this.takeLock;
    

    is: in case the original member was not declared as final, and the writer wanted to signal the programmers that will maintain this code in the future - to not, by any means, change the reference to these objects (which is achieved by the final declaration).

    UPDATE:
    This code is taken from the implementation of LinkedBlockingQueue written by Doug Lea. According to the link that assylias posted above, Marko wrote:

    Also, even when the member variable in question is not volatile but final, this idiom has to do with CPU caches as reading from a stack location is more cache-friendly than reading from a random heap location. There is also a higher chance that the local var will end up bound to a CPU register.

    For this latter case there is actually some controversy, since the JIT compiler will usually take care of those concerns, but Doug Lea is one of the guys who sticks with it on general principle.