java多线程延迟初始化单例的方法是什么?

时间:2018-07-15 21:10:27

标签: java multithreading thread-safety singleton lazy-initialization

以下两种在Java中延迟初始化线程安全单例的方法是否正确?性能上有区别吗?如果不是,那为什么我们使用Holder模式(Singleton2)而不是像Singleton1那样保持简单?

谢谢。

class Singleton1 {
    private Singleton1() {
        System.out.println("Singleton1-Constructor");
    }

    private static final Singleton1 inst1 = new Singleton1();

    public static Singleton1 getInst1() {
        return inst1;
    }
}

class Singleton2 {
    private Singleton2() {
        System.out.println("Singleton2-Constructor");
    }

    public static class Holder {
        private static final Singleton2 holderInst = new Singleton2();
    }

    public static Singleton2 getInst2() {
        return Holder.holderInst;
    }
}

public class App {
    public static void main(String[] args) {
        Singleton1.getInst1(); // without this statement the Singleton1 constructor doesnt get called.
        Singleton2.getInst2(); // without this statement the Singleton2 constructor doesnt get called.
    }
}

1 个答案:

答案 0 :(得分:2)

Singleton1并不是真正的惰性,因为如果您向Singleton1添加任何其他方法并从主类中调用它,那么静态inst1将被初始化。

尝试一下:

public class Singleton1 {
  private Singleton1() {
    System.out.println("Singleton1-Constructor");
  }

  private static final Singleton1 inst1 = new Singleton1();

  public static Singleton1 getInst1() {
    return inst1;
  }

  public static void foo() {
  }
}

public class Singleton2 {
  private Singleton2() {
    System.out.println("Singleton2-Constructor");
  }



  public static class Holder {
    private static final Singleton2 holderInst = new Singleton2();
  }

  public static Singleton2 getInst2() {
    return Singleton2.Holder.holderInst;
  }

  public static void bar() {
  }
}

public class LazyInitializationApp {

  public static void main(String[] args) {
    Singleton1.foo();
    Singleton2.bar();
  }
}

现在运行该应用程序将打印:

Singleton1-Constructor

但是它不会打印Singleton2-Constructor,因为它确实很懒。