带或不带持有者的单例=懒惰与急切初始化? [英] Singleton with or without holder = lazy vs eager initialisation?

查看:40
本文介绍了带或不带持有者的单例=懒惰与急切初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这样正确吗:

  • 使用singleton with a holder会产生延迟初始化,因为类SingletonHolder只有在Singleton.getInstance()运行时才会初始化。这依赖于SingletonHolder仅在Singleton.getInstance()内部引用。它是线程安全的,因为类加载器负责同步。
  • 使用没有持有符的单例是急切的初始化,因为一旦JAVA遇到引用Singleton的代码,它的所有静电字段都会被解析。它也是线程安全的,因为类加载器负责同步。

带限定符的单例。

public class Singleton {
   private static class SingletonHolder {
      private static final Singleton INSTANCE = new Singleton();
   }
   public static Singleton getInstance() {
      return SingletonHolder.INSTANCE;
   }
   private Singleton(){ }
}

没有持有符的单例。

public class Singleton{
   private static final Singleton INSTANCE = new Singleton();
   public static Singleton getInstance(){
      return INSTANCE;
   }
   private Singleton(){ }
}

更新以回应@Jan认为这是What is an efficient way to implement a singleton pattern in Java?副本的建议。我不同意。我不是在问什么是最好的方法:我只是在问是什么让这两个特定的实现变得懒惰而不是急于加载。像xyz's这样的答案大体上是针对懒惰和渴望的,但不是通过对比我试图检查的两个示例(或者使用相同的关键字,这就是为什么我在最初的搜索中没有出现它)。

推荐答案

作为对@sriram的响应,下面是我用来证明哪个是急切加载,哪个是延迟加载的测试。

使用托架进行惰性加载

public class Singleton {
   private static class SingletonHolder {
      static {
         System.out.println("In SingletonHolder static block.");
      }
      private static final Singleton INSTANCE = new Singleton();
   }

   public static Singleton getInstance() {
      System.out.println("In getInstance().");
      return SingletonHolder.INSTANCE;
   }

   private Singleton() {
      System.out.println("In constructor.");
   }

   private void doSomething() {
      System.out.println("Singleton working.");
   }

   public static void main(String[] args) {
      System.out.println("Start of main.");
      Singleton.getInstance().doSomething();
      System.out.println("End of main.");
   }
}

输出显示main方法在调用getInstance()之前启动,因此延迟加载。

Start of main.
In getInstance().
In SingletonHolder static block.
In constructor.
Singleton working.
End of main.

无托架的紧急加载

public class Singleton {

   static {
      System.out.println("In Singleton static block.");
   }

   private static final Singleton INSTANCE = new Singleton();

   public static Singleton getInstance() {
      System.out.println("In getInstance().");
      return INSTANCE;
   }

   private Singleton() {
      System.out.println("In constructor.");
   }

   private void doSomething() {
      System.out.println("Singleton working.");
   }

   public static void main(String[] args) {
      System.out.println("Start of main.");
      Singleton.getInstance().doSomething();
      System.out.println("End of main.");
   }

}

输出显示main方法在调用getInstance()方法后启动,因此会立即加载。

In Singleton static block.
In constructor.
Start of main.
In getInstance().
Singleton working.
End of main.

这篇关于带或不带持有者的单例=懒惰与急切初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆