Java Singleton vs static – 是否有真正的性能优势?

我正在合并一个CVS分支,其中一个较大的更改是替换它出现的Singleton模式,其抽象类具有静态初始化块和所有静态方法。

这是值得保留的东西,因为它需要合并很多冲突,我会考虑什么样的情况才能使这种重构变得有价值?

我们在Weblogic 8.1下运行这个应用程序(所以JDK 1.4.2)


对不起托马斯,让我澄清一下..

HEAD版本具有传统的单例模式(私有构造函数,getInstance()等)

分支版本没有构造函数,是一个“公共抽象类”,并将对象上的所有方法都修改为“静态”。 以前存在于私有构造函数中的代码将移动到静态块中。

然后更改类的所有用法,这会导致合并中出现多个冲突。

有一些情况发生了这种变化。

从严格的运行时性能角度来看,差异实际上可以忽略不计。 两者之间的主要区别在于“静态”生命周期与类加载器相关联,而对于单例,它是常规实例生命周期。 通常最好远离ClassLoader业务,避免一些棘手的问题,尤其是当您尝试重新加载Web应用程序时。

如果需要存储任何状态,我会使用单例,否则使用静态类。 除非需要存储某些内容,否则实例化某些内容(即使是单个实例)也没有意义。

静态不利于可扩展性,因为子类不能扩展或覆盖静态方法和字段。

它对于unit testing也很糟糕。 在unit testing中,由于无法控制类加载器,因此无法防止不同测试的副作用溢出。 在一个unit testing中初始化的静态字段将在另一个unit testing中可见,或者更糟糕的是,同时运行的测试将产生不可预测的结果。

单调使用时通常是一种好的模式。 我更喜欢使用DI框架,让我为我管理我的实例(可能在不同的范围内,如在Guice中)。

如果我的原始post是正确的理解,并且与之相关的Sun的讨论是准确的(我认为可能是这样),那么我认为你必须在清晰度和性能之间进行权衡。

问自己这些问题:

  1. Singleton对象是否使我正在做的更清楚?
  2. 我是否需要一个对象来执行此任务,还是更适合静态方法?
  3. 我是否需要通过不使用Singleton获得的性能?

根据我的经验,唯一重要的是哪一个在unit testing中更容易模拟。 我总觉得Singleton更容易自然地模仿。 如果您的组织允许您使用JMockit,那么无关紧要,因为您可以克服这些问题。

这个讨论有帮助吗? (我不知道是否禁止链接到另一个编程论坛,但我不想只引用整个讨论=))

Sun讨论这个问题

判决似乎是在大多数情况下它没有产生足够的差异,尽管技术上静态方法更有效。

编写一些代码来衡量性能。 答案将取决于JVM(Sun的JDK可能与JRockit的执行方式不同)以及应用程序使用的VM标志。