Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In ArrayBlockingQueue, why copy final member field into local final variable?

In ArrayBlockingQueue, all the methods that require the lock copy it to a local final variable before calling 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();     } } 

Is there any reason to copy this.lock to a local variable lock when the field this.lock is final?

Additionally, it also uses a local copy of E[] before acting on it:

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

Is there any reason for copying a final field to a local final variable?

like image 505
mjlee Avatar asked May 07 '10 03:05

mjlee


People also ask

Why local variables should be final?

final is the only allowed access modifier for local variables. final local variable is not required to be initialized during declaration. final local variable allows compiler to generate an optimized code. final local variable can be used by anonymous inner class or in anonymous methods.

Can final be used on method parameters and local variables?

In Java, you can qualify local variables and method parameters with the final keyword. Doing so results in not being able to reassign x and qwerty in the body of the method.

Can a local class have access to non final local variables Why?

A local inner class cannot be instantiated from outside the block where it is created in. Till JDK 7, the Local inner class can access only the final local variable of the enclosing block. However, From JDK 8, it is possible to access the non-final local variable of enclosing block in the local inner class.

Why would you make a variable final in Java?

The main purpose of effectively final variables is to enable lambdas to use local variables that are not explicitly declared final. However, the Java compiler won't perform static code optimization for effectively final variables the way it does for final variables.


2 Answers

It's an extreme optimization Doug Lea, the author of the class, likes to use. Here's a post on a recent thread on the core-libs-dev mailing list about this exact subject which answers your question pretty well.

from the post:

...copying to locals produces the smallest bytecode, and for low-level code it's nice to write code that's a little closer to the machine

like image 117
ColinD Avatar answered Oct 12 '22 13:10

ColinD


This thread gives some answers. In substance:

  • the compiler can't easily prove that a final field does not change within a method (due to reflection / serialization etc.)
  • most current compilers actually don't try and would therefore have to reload the final field everytime it is used which could lead to a cache miss or a page fault
  • storing it in a local variable forces the JVM to perform only one load
like image 39
assylias Avatar answered Oct 12 '22 13:10

assylias