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

问题描述 投票:4回答:3

我被Doug Lea的阅读ArrayBlockingQueue实现代码的一天,发现了大量的(public, default, and private)有以下引用的方法:

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

我也问过身边有一个合理的解释,但至今还没有令人满意的答案。我不明白为什么我们需要首先有这样的局部变量?什么是编码这种方式的好处(S)?

也许我在并发编程中错过了一些重要的观点。你能帮到一些线索这灯?

java
3个回答
3
投票

一个很好的理由为一个局部变量设置为可访问的类或实例变量,或者通过其中的一个访问的值的值的方法,是在其后是独立的其它线程任何修改该变量的。一些警告,这使得需要访问该值不止一次地在某个时间的特定点进行一致的计算反映了主机对象的状态,即使该国已通过返回结果的时间变化的方法。这可能是正在发生的事情,你一直都在研究代码。


2
投票

事有凑巧,我正好碰到这个链接,解释了一些编码这种方式的主要论据来了:In ArrayBlockingQueue, why copy final member field into local final variable?。请读得懂更多,相反,我希望没有得到更多的困惑。我相信它可以帮助你看看从另一角度来看这一做法。现在看来,这至少满足我的一些解决此编码风格的好奇心。


2
投票

通过所有相关的线程到一个本地副本分配final类变量的编码实践中去后,即final类变量从未被直接从一个方法中访问,相反,它总是由一个局部变量的引用引用:

final Object[] items = this.items;

final ReentrantLock lock = this.lock;

通常,你会发现在ArrayBlockingQueue和其他并发类的代码风格

以下是我的发现:

  • 这是一个习惯用法,由Doug Lea的,在多线程/并发类核心Java库的主要作者提出流行
  • 这种编码的做法(或者更确切地说,黑客)的主要考虑是一个小的性能优化早在Java 5的时代
  • 这是值得商榷的,如果这样的技巧可以有性能增益;有些人认为它与现代的编译器相反;其他人则认为它不需要

所以我的征收是我们不应该鼓励采用这种做法。因为在许多应用中,你不需要它。干净的代码也许不是一个小的性能提升更重要;更何况没有人是100%肯定这(性能增益)是否是这种情况了。

© www.soinside.com 2019 - 2024. All rights reserved.