【问题标题】:Java Double checked locking - initialization method [duplicate]Java双重检查锁定-初始化方法[重复]
【发布时间】:2015-11-12 13:07:38
【问题描述】:

考虑这个例子:

class SomeClass{
     private Foo val;

     String getVal(){
           if(val == null){
                synchronized(this){
                      if(val ==null)
                           val = generateFoo();
                }
          }
     }

     Foo generateFoo(){
          //some code
          return new Foo();
     }
}

在这种情况下需要 volatile 吗?

【问题讨论】:

    标签: java multithreading double-checked-locking


    【解决方案1】:

    根据The "Double-Checked Locking is Broken" Declaration 看来,需要使其变为易失性。

    JDK5 和更高版本扩展了 volatile 的语义,因此系统不允许对 volatile 的写入相对于任何先前的读取或写入重新排序,并且对 volatile 的读取不能相对于任何后续读取重新排序或写。有关详细信息,请参阅 Jeremy Manson 博客中的此条目。

    通过此更改,可以通过将辅助字段声明为易失性来使双重检查锁定习惯用法起作用。这在 JDK4 及更早版本下不起作用。

    但是我可以提出不同的建议吗?

    不要使用singletons-the-design-pattern。在 API 中明确说明它应该是单例。允许您班级的用户将其用作单例,但要以当时有意义的方式使用,例如使用Singleton-as-a-scopeService Locator

    这将更容易测试,更容易使用,这意味着每次使用单例时杀死小猫的女神将不必杀死小猫。大家都很开心。

    【讨论】:

      【解决方案2】:

      不需要。 你可以去原子参考。

      AtomicReference atomicStringReference = 新的 AtomicReference(val);

      在这里查看:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多