为什么在调用其方法(最佳实践或出于特定原因)之前将最终字段变量分配给本地副本?

在检查ArrayBlockingQueue的源代码时,我注意到在调用对象实例的任何方法之前,已将最终字段分配给局部变量。 这是为了达到特定目的吗?

 public E peek() { final ReentrantLock lock = this.lock; lock.lock(); try { return (count == 0) ? null : items[takeIndex]; } finally { lock.unlock(); } } 

这里有一个讨论。 基本上它是一种优化,允许更快地访问锁。 即使this.lock是最终的,jvm仍然会在每次访问this.lock时进行字段查找,通过制作最终副本,它会稍快一些。

代码使用此模式,因为它希望允许更改this.lock字段。

假设两个线程正在访问ArrayBlockingQueue对象。 其中一个运行peek()方法,另一个更改锁。

如果peek()的代码没有在本地变量lock捕获this.lock的原始值,那么它将在新分配的锁上调用unlock (在最后关闭时),因为它需要在原锁。

(这是一个很好的解释,但是 – 不幸的是 – 它与ArrayBlockingQueue类无关,因为lock字段是最终的)。