-4

考虑这个例子:

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 是必要的吗?

4

2 回答 2

0

没有没有必要。你可以去原子参考。

AtomicReference atomicStringReference = new AtomicReference(val);

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

于 2015-11-12T13:29:34.593 回答
0

根据“双重检查锁定被破坏”声明,似乎需要使其变得易变。

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

通过此更改,可以通过将辅助字段声明为 volatile 来使 Double-Checked Locking 习惯用法起作用。这在 JDK4 及更早版本下不起作用。

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

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

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

于 2015-11-12T13:15:10.340 回答