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

我们从以下方面更改现有代码是否有任何好处:


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”不是一个好习惯。对于每个类变量。


Helenr
浏览 87回答 1
1回答

慕雪6442864

复制到局部变量更高效、更正确。更高效:假设在一般情况下,myVariable是非空的。在第一个版本中,您对 执行两次读取myVariable,一次检查 null,一次返回值。在第二个版本中,您执行一次读取myVariable和两次读取tmp(局部变量访问,这是微不足道的)。使用 volatile 的全部意义在于强大的内存保证,而这些保证意味着两次读取对一次读取的性能影响很大。更正确:假设这myVariable是某种需要定期刷新的“缓存”。即有一个后台线程定期设置,myVariable以便null在下次读取时重新加载。在第一个版本中,您对myVariable. 第一次读取可能返回非null,然后“缓存刷新”逻辑运行并设置myVariable为null。第二次读取(返回值)然后返回null!在第二个版本中,始终tmp是您测试的值(当然假设永远不会返回)。nullgetNewValue()null注意使用“这个”。是此代码中的一种风格选择,与正确性或性能问题无关。这在很大程度上只是扩展了https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java中所述的内容。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java