Java Singleton设计模式实现

时间:2015-02-26 05:04:53

标签: java design-patterns singleton

Singleton类的实现可以像下面这样简单:

public class MyClass {
    private final static MyClass myClass = new MyClass();
    private MyClass() {}
    public static MyClass getInstance() {
        return myClass;
    }
}

结束:

public class MyClass {
    private final static MyClass myClass;
    private MyClass() {}
    public static MyClass getInstance() {
        if(null == myClass) {
            myClass = new MyClass();
        }
        return myClass;
    }
}

上述实施中哪个更好&为什么呢?

我观察到的一件事是对于第一个实现,对象构造函数在静态块之前被调用(如果有的话)。

此外,如果第二个实现的线程安全版本(可能是双重空检查和同步块),这应该是首选吗?

3 个答案:

答案 0 :(得分:1)

是。你可以使用第一个版本,但我建议你使用enum。维基百科在Singleton上的条目说

  

在他的书 Effective Java 的第二版中,Joshua Bloch声称​​ a single-element enum type is the best way to implement a singleton 支持任何支持枚举的Java。

这样的东西
public enum Singleton {
    INSTANCE;
}

答案 1 :(得分:1)

yoy需要注意定义单例类的原则规则是:

  1. 私有构造函数 - 限制从其他类创建对象
  2. 私有静态字段变量,它保存同一个类的唯一实例
  3. 公共静态方法,用于在请求时返回此实例
  4. 这取决于您的需求,是否需要提前初始化或延迟初始化。第一个是早期初始化的示例,而第二个是延迟初始化的示例。有多种方法可以定义完美的Singleton类

答案 2 :(得分:1)

我想对单身设计模式有所了解。

您的第一个代码段

public class MyClass {
    private final static MyClass myClass = new MyClass();
    public static MyClass getInstance() {
        return myClass;
    }
}

上面的方法工作正常但有缺点,因为实例在实际需要之前就已经创建了很多,所以在运行时想到如果实例不大的情况,你可以保留它,如果它没有被使用但是如果它很大然后创建实例的目的是什么。这种方法称为Eager初始化

下面显示的代码表示第二种称为Lazy初始化的方法 公共类MyClass {

    private final static MyClass myClass;
    public static MyClass getInstance() {
        if(null == myClass) {
            myClass = new MyClass();
        }
        return myClass;
    }
}

但是在这里,你的代码还有一个缺点,让我们理解上面代码中的缺陷

让我们考虑我们有两个线程,即T1和T2,两个线程都用于创建实例并执行检查 null == myClass ,现在两个线程都已将实例变量识别为null,因此假设它们必须创建一个实例。它们按顺序进入同步块并创建实例。最后,我们的应用程序中有两个实例。

这可以通过简单的双重检查锁定来解决。下面的代码将向您展示更好的实现方式。请注意 - 我在代码中使用了私有构造函数。

public class MyClass {
    private final static MyClass myClass = null;

//private constructor
private MyClass(){
}
    public static MyClass getInstance() {
        if(myClass == null) {
synchronized (MyClass.class){
// Double check
if(myClass == null){
            myClass = new MyClass();
        }
}

}
        return myClass;
    }
}