Java Singleton vs static - 有真正的性能优势吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28241/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:20:30  来源:igfitidea点击:

Java Singleton vs static - is there a real performance benefit?

javadesign-patternssingleton

提问by

I am merging a CVS branch and one of the larger changes is the replacement wherever it occurs of a Singleton pattern with abstract classes that have a static initialisation block and all static methods.

我正在合并一个 CVS 分支,其中一个较大的变化是用具有静态初始化块和所有静态方法的抽象类替换单例模式出现的任何地方。

Is this something that's worth keeping since it will require merging a lot of conflicts, what sort of situation would I be looking at for this refactoring to be worthwhile?

这是值得保留的东西,因为它需要合并很多冲突,我会在什么样的情况下寻找这种重构值得?

We are running this app under Weblogic 8.1 (so JDK 1.4.2)

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



sorry Thomas, let me clarify..

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

the HEAD version has the traditional singleton pattern (private constructor, getInstance() etc)

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

the branch version has no constructor, is a 'public abstract class' and modified all the methods on the object to be 'static'. The code that used to exist in the private constructor is moved into a static block.

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

Then all usages of the class are changed which causes multiple conflicts in the merge.

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

There are a few cases where this change was made.

在少数情况下进行了这种更改。

采纳答案by Damien B

From a strict runtime performance point of view, the difference is really negligible. The main difference between the two lies down in the fact that the "static" lifecycle is linked to the classloader, whereas for the singleton it's a regular instance lifecycle. Usually it's better to stay away from the ClassLoader business, you avoid some tricky problems, especially when you try to reload the web application.

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

回答by EdgarVerona

Does this discussion help? (I don't know if it's taboo to link to another programming forum, but I'd rather not just quote the whole discussion =) )

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

Sun Discussion on this subject

Sun 关于这个主题的讨论

The verdict seems to be that it doesn't make enough of a difference to matter in most cases, though technically the static methods are more efficient.

结论似乎是在大多数情况下它并没有产生足够的影响,尽管从技术上讲静态方法更有效。

回答by Thomas Owens

If my original post was the correct understanding and the discussion from Sun that was linked to is accurate (which I think it might be), then I think you have to make a trade off between clarity and performance.

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

Ask yourself these questions:

问问自己这些问题:

  1. Does the Singleton object make what I'm doing more clear?
  2. Do I need an object to do this task or is it more suited to static methods?
  3. Do I need the performance that I can gain by not using a Singleton?
  1. Singleton 对象是否使我在做的事情更清楚?
  2. 我需要一个对象来完成这个任务还是更适合静态方法?
  3. 我是否需要通过不使用单例获得的性能?

回答by levand

I would use a singleton if it needed to store any state, and static classes otherwise. There's no point in instantiating something, even a single instance, unless it needs to store something.

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

回答by Cem Catikkas

From my experience, the only thing that matters is which one is easier to mock in unit tests. I always felt Singleton is easier and natural to mock out. If your organization lets you use JMockit, it doesn't matter since you can overcome these concerns.

根据我的经验,唯一重要的是在单元测试中哪个更容易模拟。我一直觉得 Singleton 更容易和自然地模拟。如果您的组织允许您使用 JMockit,这并不重要,因为您可以克服这些问题。

回答by Mark Renouf

Static is bad for extensibility since static methods and fields cannot be extended or overridden by subclasses.

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

It's also bad for unit tests. Within a unit test you cannot keep the side effects of different tests from spilling over since you cannot control the classloader. Static fields initialized in one unit test will be visible in another, or worse, running tests concurrently will yield unpredictable results.

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

Singleton is generally an ok pattern when used sparingly. I prefer to use a DI framework and let that manage my instances for me (possibly within different scopes, as in Guice).

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

回答by Rob Spieldenner

Write some code to measure the performance. The answer is going to be dependent on the JVM(Sun's JDK might perform differently than JRockit) and the VM flags your application uses.

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