While browsing through the source code of the java.util.concurrency package, I noticed an idiomatic use of ReentrantLock that I had not seen before: member RentrantLock variables were never accessed directly from within a method - they were always referenced by a local variable reference.
Style #1 e.g from java.util.concurrent.ThreadPoolExecutor
private final ReentrantLock mainLock = new ReentrantLock();
...
// why a local reference to final mainlock instead of directly using it?
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
...
} finally {
mainLock.unlock();
}
However, in other places the final member variable is used directly, without first obtaining a local reference.
Style #2 e.g. from Java Concurrency in Practice
private final Lock lock = new ReentrantLock();
...
// here the final lock is used directly
lock.lock();
try {
...
} finally {
lock.unlock();
}
I would like to understand what are the benefits of using Style #1 over Style #2?
Thanks
Update
Thanks for all of responses, especially Ben Manes for first identifying performance. As a result I was able to discover the following additional details
- Doug Lea introduced this idiom in 2003 with a comment "cache finals across volatiles"
- According to Doug, it is "for performance-critical code like that inside j.u.c." and while "It's not a recommended practice", he "does not discourage it either"
- Brian Goetz (author of JCIP) also agrees that unless it is for performance-critical applications "don't worry"