这是一个正确的Singleton实现吗?

时间:2013-01-29 05:53:06

标签: java singleton

  

可能重复:
  What is an efficient way to implement a singleton pattern in Java?

我是设计模式和学习阶段的新手。最近我了解了Singleton模式,我查看了我工作的公司代码。 我发现下面的代码片段根据Singleton规则看起来不正确,即我们不应该同步一个方法但是要同步一个块。并且线程应始终在进入块之前检查“ïnstance”变量的值是否为null。我的理解是正确的还是有一些逻辑可以用以下方式编码?

public class CustomLogger {

private static CustomLogger instance;

private CustomLogger(){
    some code here....
}

public static synchronized CustomLogger getInstance(){
    if (instance == null){
        instance = new CustomLogger();
    }
    return instance;
}
}

3 个答案:

答案 0 :(得分:1)

你的方法是正确的,因为你的getInstance()方法是同步的。但只有第一次调用getInstance()时才需要同步。也就是说,当我们创建单例对象时。我们需要已经创建了所有实例的其他情况并且不需要同步访问。

另一种方法是单独同步单例创建部分。但这种方法(双重锁定)有许多问题。 请参阅:http://www.ibm.com/developerworks/java/library/j-dcl/index.html

从Java 5开始,创建单例的最佳方法是使用Enums。

答案 1 :(得分:1)

如果你必须使用单身人士,那就急切地构建它们,而没有所有有趣的业务同步。那就是:

public class CustomLogger {
  private static CustomLogger instance = new CustomLogger();

  public static CustomLogger instance() { return instance;
}

在类中单例实例的延迟初始化很少有任何好处 - 当有问题的类被加载以供活动使用时,将构造实例,这通常是在调用instance()时,本身应该是无论如何都会发生懒惰的实例化。

我怀疑你所展示的代码的原因是由于旧的C ++程序员对加载顺序持谨慎态度;在Java中没有问题的东西(在JLS中明确指定了加载顺序)。

答案 2 :(得分:0)

  

我们不应该同步一个方法,而是要同步一个块。

错误。两者都很好,但是将块同步是一种更好的方法。

  

检查“ïnstance”变量的值之前是否为null   进入区块

这就是这条线正在做什么

if (instance == null)