-1

可能重复:
在 Java 中实现单例模式的有效方法是什么?

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

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;
}
}
4

3 回答 3

1

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

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

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

于 2013-01-29T05:58:57.397 回答
1

如果您必须使用单例,只需急切地构建它们,而不要使用同步进行所有有趣的业务。那是:

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

  public static CustomLogger instance() { return instance;
}

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

我怀疑您显示代码的原因是由于老 C++ 程序员对加载顺序持谨慎态度;在 Java 中不是问题的东西(在 JLS 中很好地指定了加载顺序)。

于 2013-01-29T06:01:34.773 回答
0

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

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

在进入块之前检查“ïinstance”变量的值是否为空

这就是这条线正在做的事情

if (instance == null)
于 2013-01-29T05:58:11.640 回答