探索 OpenJDK 8 中 java.util.LinkedList 的代码,我发现了以下代码。代码很简单,但我对将第一个节点的引用保存到第二行代码中的常量感到困惑。据我了解,这段代码将被内联为一行而不进行引用复制。我对吗?如果是这样,为什么在这种情况和类似情况下需要复制参考文献(这样的习惯用法可能出现在java.util.LinkedList的一半方法中)?
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
我的第一个想法是它以某种方式帮助并发,但是 LinkedList 不允许并发访问(除非您自己承担风险),所以我想这是优化器的一些提示,但无法弄清楚它应该如何工作。
我的第一个想法是它在某种程度上有助于并发......
...所以我想这是优化器的一些提示...
两个都。 :-) 事实是LinkedList
不支持并发并不意味着作者不会遵循良好实践,它告诉编译器和 JIT 他们应该只查找first
once.
如果没有f
局部变量,我们有:
public E peek() {
return (this.first == null) ? null : this.first.item;
}
我已经添加了隐含的this.
强调first
是一个实例字段。
所以如果this.first == null
部分在线程 A 上求值,然后this.first
在线程 B 上发生更改,当this.first.item
在线程 A 上求值,它可能会抛出错误,因为this.first
已经成为null
同时。这是不可能的f
, 因为f
是本地的;仅运行的线程peek
打电话就会看到它。
The final
部分都是很好的代码内文档(因为作者从未打算更改f
)并向优化器提示我们永远不会改变f
,这意味着当需要优化时,它可以将其优化到其寿命的一英寸之内,因为它知道它只需要读取this.first
once然后可以使用寄存器或堆栈值null
检查并退货。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)