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

StackOverflow https://stackoverflow.com/questions/19548921

Question

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?

Était-ce utile?

La solution 2

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.

Autres conseils

Can anyone explain why we assign this.count to a local variable

It might potentially improve the performance since accessing a local variable is slightly cheaper than accessing an instance variable. This post seems to support this. However, they also say that it is an extreme optimization which might not be necessary.

and also why the local variable declared as final?

It seems that the field count is defined as final in the source code as well. They might just want to be consistent by declaring the local variable as final.

I'm sure it has to do with various compiler optimizations. In general, compiler hints like this aren't necessary, as the compiler in theory should be able to figure this particular optimization out itself, but the JDK writers probably have better knowledge about the actual practical implementation of the compiler, and therefore know that this will create faster bytecode.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top