Java双重检查锁定,这段代码是否有效?

3

我已经阅读了“双重检查锁定是错误的”声明。但我想知道如果我通过一个函数创建对象,那么是否可以?

    class Foo { 
      private Helper helper = null;
      public Helper getHelper() {
        if (helper == null) 
          synchronized(this) {
            if (helper == null) 
              helper = createHelper();
          }    
        return helper;
      }
      private Helper createHelper() {
         return new Helper();
      }
      // other functions and members...
    }

不,这里什么也没改变。方法调用没有添加任何内容:因此它没有改变任何东西。 - user166390
不,这个函数没有添加任何东西,但它仍然没有出现故障。 - Tobias Ritzau
1
@TobiasRitzau 我想它仍然是损坏的。据我所知,它需要是一个易失性字段,才能在Java 5 MM下得到保证。请参阅链接文章。 - user166390
@pst,你是对的。抱歉... - Tobias Ritzau
2
各位,请认真阅读链接文章,不要只是草率地浏览。helper字段需要声明为volatile。私有函数是无用的。从JSE5开始,它将起作用。 - Christian Schlichtherle
1个回答

5

添加一个函数不会有任何影响,你的函数也没有实现任何功能。

但是,如果你将其声明为 volatile,它将从Java 1.5开始正常工作。

private volatile Helper helper = null;

在Java中,一种正确的延迟初始化方式是“Initialization-on-demand holder idiom”。这种方式依赖于内部类在被引用之前不会被加载的事实。请参考Initialization-on-demand holder idiom
class Foo {
    private static class HelperHolder {
        public static Helper helper = new Helper();
    }

    public static Helper getHelper() {
        return HelperHolder.helper;
    }
}

那么,如果我像这样编写createHelper helper = Foo.getHelper();,可以吗? - jinghui70
@jinghui70 是的。非常好。 - Amit Deshpande

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接