【ArrayBlockingQueue 方法里锁赋值给一个本地 final 变量】
public class ArrayBlockingQueue<E> {
/** Main lock guarding all access */
final ReentrantLock lock;
public E take() throws InterruptedException {
// 就是下面这行,为什么要把 this.lock 赋值给一个本地 final 变量
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}
}
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.
– stackoverflow - arrayblockingqueue-why-copy-final-memever-field-into-local-final-variable
It’s a coding style made popular by Doug Lea.
It’s an extreme optimization that probably isn’t necessary;
you can expect the JIT to make the same optimizations.
(you can try to check the machine code yourself!)
Nevertheless, 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.Also, optimizations of finals (can cache even across volatile
reads) could be better. John Rose is working on that.For some algorithms in j.u.c,
copying to a local is necessary for correctness.
极致优化,让编译器(本地编译器或者 JIT)更有可能把后续对堆上同一个地址的访问"优化"成对栈上比较近的地址或寄存器的访问。