使用额外的局部变量从方法中引用类变量

时间:2019-02-01 14:35:14

标签: java

第二天,我正在阅读Doug Lea的ArrayBlockingQueue实现代码,并注意到许多方法(public, default, and private)具有以下参考:

final Object[] items = this.items;
final ReentrantLock lock = this.lock;

我要求周围有一个合理的解释,但到目前为止,还没有令人满意的答案。我不太确定为什么我们首先需要有这样的局部变量?用这种方式编码的好处是什么?

也许我错过了并发编程中的一些要点。您能帮忙阐明一下吗?

3 个答案:

答案 0 :(得分:3)

将局部变量设置为可访问类或实例变量的值或通过其中一个 可访问值的方法的一个很好的理由是此后与任何修改无关到其他线程对该变量的访问。有一些警告,这允许需要多次访问该值的方法来执行一致的计算,以反映某个特定时间点宿主对象的状态,即使该状态在返回结果时已更改。这可能是您正在研究的代码中发生的事情。

答案 1 :(得分:2)

碰巧我碰到了这个链接,它解释了这种编码方式的一些主要论点:[In ArrayBlockingQueue, why copy final member field into local final variable?。请阅读它以了解更多信息,相反,我希望不再感到困惑。我相信它可以帮助您从另一个角度看待这种做法。似乎至少满足了我对这种编码风格的一些好奇。

答案 2 :(得分:2)

在完成了将所有最终类变量分配给本地副本的编码实践后,即从未从方法内部直接访问最终类变量,而是始终由局部变量引用对其进行引用: / p>

final Object[] items = this.items;

final ReentrantLock lock = this.lock;

通常,您会在ArrayBlockingQueue和其他并发类中找到这种代码样式

以下是我的发现:

  • 这是一种惯用用法,受到主要作者Doug Lea的欢迎 多线程/并发类上的核心Java库
  • 此编码实践(或更确切地说是hack)的主要考虑因素是 Java 5时代的性能优化
  • 这种技巧是否可以提高性能是有争议的;有人认为这是相反的 使用现代编译器;其他人则认为不需要

所以我的看法是,不应该鼓励我们采取这种做法。因为在许多应用程序中您不需要它。干净的代码可能比获得少量性能更为重要。更alone论的是,没有人能100%确定这种情况(性能提升)是否已经成立。