为了账号安全,请及时绑定邮箱和手机立即绑定

我们真的需要在本地复制 this.myVolatile 来执行 Java 8 中的同步

我们真的需要在本地复制 this.myVolatile 来执行 Java 8 中的同步

Helenr 2023-03-17 17:07:45
我们从以下方面更改现有代码是否有任何好处:class MyClass {    volatile Object myVariable;    Object myMethod() {        if (myVariable == null) {            synchronized(this) {                if (myVariable == null) {                    myVariable = this.getNewValue();                }            }        }        return myVariable;    }}到class MyClass {    volatile Object myVariable;    Object myMethod() {        Object tmp = this.myVariable;        if (tmp == null) {            synchronized(this) {                tmp = this.myVariable;                if (tmp == null) {                    this.myVariable = tmp = this.getNewValue();                }            }           }        return tmp;    }}我不明白在使用之前在本地复制 this.myVariable 有什么意义,而且我认为使用“this”不是一个好习惯。对于每个类变量。
查看完整描述

1 回答

?
慕雪6442864

TA贡献1812条经验 获得超5个赞

复制到局部变量更高效、更正确。

更高效:假设在一般情况下,myVariable是非空的。在第一个版本中,您对 执行两次读取myVariable,一次检查 null,一次返回值。在第二个版本中,您执行一次读取myVariable和两次读取tmp(局部变量访问,这是微不足道的)。使用 volatile 的全部意义在于强大的内存保证,而这些保证意味着两次读取对一次读取的性能影响很大。

更正确:假设这myVariable是某种需要定期刷新的“缓存”。即有一个后台线程定期设置,myVariable以便null在下次读取时重新加载。在第一个版本中,您myVariable. 第一次读取可能返回非null,然后“缓存刷新”逻辑运行并设置myVariablenull。第二次读取(返回值)然后返回null!在第二个版本中,始终tmp是您测试的值(当然假设永远不会返回)。nullgetNewValue()null

注意使用“这个”。是此代码中的一种风格选择,与正确性或性能问题无关。

这在很大程度上只是扩展了https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java中所述的内容。


查看完整回答
反对 回复 2023-03-17
  • 1 回答
  • 0 关注
  • 86 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信