Java 单例设计模式实现

Java Singleton Design Pattern implementation

Singleton class 的实现是否可以像下面这样简单:

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;
    }
}

以上实现中哪个更好,为什么?

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

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

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

In the second edition of his book Effective Java, Joshua Bloch claims that a single-element enum type is the best way to implement a singleton for any Java that supports enums.

类似

public enum Singleton {
    INSTANCE;
}

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

  1. 私有构造函数 - 限制其他 classes
  2. 的对象创建
  3. 私有静态字段变量,其中包含相同的唯一实例class
  4. 一个 public 静态方法,在请求时用于 return 此实例

这取决于你想要它的方式,你是想要早期初始化还是延迟初始化。第一个是早期初始化的例子,而第二个是延迟初始化的例子。有多种方法可以定义一个完美的单例Class

我想简单介绍一下单例设计模式。

你的第一个代码片段

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

上述方法工作正常但有缺点,因为实例在实际需要它之前就已经创建了很多,所以在 运行-time 想想如果实例不大你可以保留它的情况未使用,但如果它很大,那么创建 instance.This 方法的目的是什么,称为 Eager initialization

下面显示的代码表示第二种方法称为延迟初始化 public class 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;
    }
}