Singleton 实现中的按需初始化惯用法与简单静态初始化器
当使用静态初始化实现线程安全单例时,Initialize-On-Demand 习惯是否真的有必要,或者实例的简单静态声明就足够了?
将实例简单声明为静态字段:
class Singleton
{
private static Singleton instance=new Singleton();
private Singleton () {..}
public static Singleton getInstance()
{
return instance;
}
}
vs
class Singleton {
static class SingletonHolder {
static final Singleton INSTANCE = new Singleton();
}
private Singleton () {..}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
我问这个是因为 Brian Goetz 推荐本文中的第一种方法:
http://www.ibm.com/developerworks/java/library/j-dcl/index.html
而他在本文中建议后者
http://www.ibm.com/developerworks/library/j-jtp03304/
后一种方法是否提供了前一种方法所没有的任何好处?
Is the Initialize-On-Demand idiom really necessary when implementing a thread safe singleton using static initialization, or would a simple static declaration of the instance suffice?
Simple declaration of instance as static field:
class Singleton
{
private static Singleton instance=new Singleton();
private Singleton () {..}
public static Singleton getInstance()
{
return instance;
}
}
vs
class Singleton {
static class SingletonHolder {
static final Singleton INSTANCE = new Singleton();
}
private Singleton () {..}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
I ask this because Brian Goetz recommends the 1st approach in this article:
http://www.ibm.com/developerworks/java/library/j-dcl/index.html
while he suggests the latter in this article
http://www.ibm.com/developerworks/library/j-jtp03304/
Does the latter approach provide any benefits that the former doesn't?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,我能说的是这些文章是 7-9 岁的。
现在我们有> Java 1.5,我们拥有枚举
enum
的能力。根据“Josh Block”,编写单例的最佳方法是编写单元素枚举,但对于您的问题,我想使用这两种实现都没有问题。我个人更喜欢第一个选项,因为它简单易懂。
但要注意漏洞,通过序列化和反序列化对象或克隆对象,我们可以在同一个 JVM 中同时创建更多这些类的对象。
还要使类成为最终类,因为我们可以通过扩展类来违反单例。
Well what i can say These articles are 7-9 years old.
Now we have > Java 1.5 where we have power of enumeration
enum
. According to 'Josh Block' The best way to write a singleton is to write a Single Element enumBut for your question I guess there is no issue in using either of the implementations. I personaly prefer the first option because its straightforward, simple to understand.
But watch out for the loop holes that we can be able to create more objects of these class in the same JVM at the same time by serializing and deserializing the object or by making the clone of the object.
Also make the class final, because we can violate the singleton by extending the class.
在第一种方法中,一旦加载
Singleton
类,就会创建您的单例。在另一种情况下,一旦您调用 getInstance() 方法,它将被创建。在调用getInstance
之前,Singleton
类可能有多种原因需要加载。因此,当您实际使用它时,您很可能会更早地初始化它,这违背了延迟初始化的目的。是否需要延迟初始化是一个单独的故事。In first approach your singleton will get created once you load
Singleton
class. In the other, it will get created once you callgetInstance()
method.Singleton
class may have many reasons to get loaded before you callgetInstance
. So you will most likely initialize it much earlier when you actually use it and that defeats the purpose of lazy initialization. Whether you need lazy initialization is a separate story.简单声明模式在加载类 Singleton 时构造单例。当调用 Singeton.getInstance() 时,即加载类 SingetonHolder 时,按需初始化习惯用法会构造单例。
所以除了时间之外,这些都是相同的;第二个选项允许您延迟初始化。何时选择其中之一取决于(除其他外)您在 Singleton 构造函数中做了多少工作。如果数量很多,您可能会发现通过按需初始化缩短了应用程序启动时间。
也就是说,我的建议是尽量不要在那里做太多事情,以便最简单的模式适合您。
-dg
The simple declaration pattern constructs the singleton when when the class Singleton is loaded. The initialize-on-demand idiom constructs the singleton when Singeton.getInstance() is called -- i.e., when class SingetonHolder is loaded.
So these are the same except for time; the second option allows you delay initialization. When to choose one or the other depends on (among other things) how much work you are doing in Singleton's constructor. If it's a lot, you may see improved application startup time with initialization-on-demand.
That said, my advice is to try not to do too much there so that the simplest pattern works for you.
-dg