Singleton Pattern的最佳解决方案是什么?

时间:2013-06-09 06:54:40

标签: java design-patterns

如果使用INSTANCE holder类来实现Singleton Pattern,编译器将生成另一个名为classname $ 1.class的类文件。您可以通过以下链接找到问题:here 。所以我的问题是Singleton Pattern的解决方案是什么?仔细检查?

4 个答案:

答案 0 :(得分:3)

您可以使用简单的枚举。

public enum Singleton {
    INSTANCE;
}

您可以简单地INSTANCE访问Singleton.INSTANCE,而不是调用getInstance()方法。默认情况下,创建Enum实例是线程安全的。

答案 1 :(得分:3)

您似乎在问这个单例代码如何实现线程安全初始化:

public final class Test {
     static final class TestHolder {
         private static final Test INSTANCE = new Test();
     }     

     private Test() {}

     public static Test getInstance() {
         return TestHolder.INSTANCE;
     }
}

解决方案的线程安全性得到保证,因为:

  • 静态初始化以线程安全的方式执行,
  • 初始化后,可以使用final变量而无需进一步同步。

没有进行双重检查锁定。

请注意,此特定模式是线程安全且延迟初始化。如果你想要非线性初始化的线程安全单例,那么:

public final class Test {
     private static final Test INSTANCE = new Test();

     private Test() {}

     public static Test getInstance() {
         return INSTANCE;
     }
}

enum作为单身人士”的做法也是可以接受的......尽管工程师Dollery说道。

使用双重检查锁定的延迟初始化可以从Java 5开始正确实现(如果使用volatile正确执行),但在Java 1.4.x及更早版本中,习惯用法已被破坏。

答案 2 :(得分:1)

我会在jdk 1.5之后使用enum。查看htis链接了解详情:http://javarevisited.blogspot.in/2012/07/why-enum-singleton-are-better-in-java.html

  1. 不建议使用双重检查锁定,但不提供性能。
  2. 您提到的链接中的解决方案是使用静态内部类的有效解决方案,因为它不使用同步并使用延迟加载,但枚举最容易实现以及性能。
  3. 下面的文章解释了为什么双重检查锁定可能是错误的选择 [正如Thomas指出的那样,beow文章中提到的双重检查锁定问题已在Java 1.5中修复]:http://www.ibm.com/developerworks/java/library/j-dcl/index.html < / p>

答案 3 :(得分:1)

根据您的部署体系结构,在Java中实现单例变得非常困难。当你谈论单身人士时,你还必须谈论他们的范围/背景。因为很少有人理解这些单身人士经常被称为邪恶,被认为是反模式。

如果您在应用程序服务器之外部署到单个jvm,那么惯用方法是在其自身内实现该类的私有最终静态实例,并通过适当命名的方法公开它(getInstance()是常见的) ,并使类的构造函数私有。这是一个约束单个类加载器和单个jvm的单例。

然而,这种情况非常罕见。

在所有其他情况下,您必须考虑类加载器问题以及将代码部署到多个jvms /服务器的问题。在典型的Java EE应用程序容器中,通常使用自己的类加载器加载每个war。如果每个战争都依赖于一个包含单身的战利品,他们每个人都会得到他们自己的单身人士副本。这可能没问题,如果单例是用于数据库连接,那么你可以使用它们。但是,如果单例应该保护对有限资源的访问,那么这不会很好,因为你将有一个类能够按webapp访问该资源。你的单身人士的范围是容器范围。

在完整的企业部署中,集群和实时故障转移会变得更糟。在此环境中,您可以同时运行许多软件副本。很难想象在这个范围内工作的只有java的单例 - 企业范围。在这个级别,你需要弄清楚单一创建或执行的单一事实来源(如果可以有多个实例,但一次只能处理一个请求),以及你创建的所有单例同一类型必须遵循单一的事实来源 - 企业信号量。