Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java多线程惰性初始化单例哪种方法?_Java_Multithreading_Thread Safety_Singleton_Lazy Initialization - Fatal编程技术网

java多线程惰性初始化单例哪种方法?

java多线程惰性初始化单例哪种方法?,java,multithreading,thread-safety,singleton,lazy-initialization,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 = n

以下两种在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.
    }
}

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构造函数,因为它确实是懒惰的。

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构造函数,因为它确实是懒惰的。

第二个选项的可能副本,
Singleton2
,允许您在不触发实例构造的情况下执行其他静态方法(如果有的话)。但是,通常情况下,
Holder
类是
private static
,您可以在singleton类上使用
public static
方法公开实例。至少我一直都是这么看的。对于那些认为它是重复的人…请看下面Pietro Boido提供的解释。建议职位上没有人以同样的方式解释过。有些人需要更多的解释,所以请不要忽略问题,因为你认为已经有类似的问题了。谢谢,请看一下彼得罗·博伊多在回答中所说的。但是,我认为Pietro更直接。第二个选项的可能副本,
Singleton2
,允许您在不触发实例构造的情况下执行其他静态方法(如果有的话)。但是,通常情况下,
Holder
类是
private static
,您可以在singleton类上使用
public static
方法公开实例。至少我一直都是这么看的。对于那些认为它是重复的人…请看下面Pietro Boido提供的解释。建议职位上没有人以同样的方式解释过。有些人需要更多的解释,所以请不要忽略问题,因为你认为已经有类似的问题了。谢谢,请看一下彼得罗·博伊多在回答中所说的。不过,我会说,我认为皮埃特罗更直接。谢谢皮埃特罗·博伊多的详细答复。但是从线程安全的角度来看,这两种解决方案都是安全的吗?谢谢Pietro Boido的详细回复。但是从线程安全的角度来看,这两种解决方案都是安全的吗?