有或没有持有者的单例 = 惰性初始化 vs 急切初始化?

2023-11-30

它是否正确:

  • Using a 带支架的单例给出延迟初始化,因为该类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(){ }
}

Update回应@jan的建议,这是重复的在 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方法开始after the getInstance()方法被调用,因此被急切地加载。

In Singleton static block.
In constructor.
Start of main.
In getInstance().
Singleton working.
End of main.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有或没有持有者的单例 = 惰性初始化 vs 急切初始化? 的相关文章

随机推荐

  • GO结构定义中的字符串文字[重复]

    这个问题在这里已经有答案了 在这个结构体定义中 type API struct Message string json message 该字符串的含义是什么 json 消息 以及如何访问它 如果可以访问 先感谢您 这些是结构标签 该结构标记
  • 更改 foreach 内的集合

    这是我的代码 foreach OrderItem item in OrderInfo order orderItemViews Single i gt i numericUpDown Name item id ToString numeri
  • Excel VBA - 合并一个单元格中具有重复值的行并合并其他单元格中的值

    我试图在一列中查找重复值并将第二列的值合并到一行中 我还想对第三列中的值求和 例如 A B C D h 4 w 3 h 4 u 5 h 4 g 7 h 4 f 4 k 9 t 6 k 9 o 6 k 9 p 9 k 9 j 1 会成为 A
  • 如何打印列表更加美观?

    这类似于如何在 Python 中 漂亮地 打印列表 但我想更好地打印列表 没有括号 撇号和逗号 甚至在列中更好 foolist exiv2 devel mingw libs tcltk demos fcgi netcdf pdcurses
  • 使用 sf 围绕点(质心)创建网格

    我有 EURO CORDEX 气候数据 该数据位于 11 度旋转的极网格上 我通过将投影转换为 WGS84 来预先准备好这些数据 数据以点的形式出现 代表方形网格的质心 我需要创建围绕这些点的方形网格 我已经导出了实现此目的的通用方法 但网
  • 命令“C:\Main\Src\.nuget\nuget.exe Restore -SolutionDirectory ..\”退出,代码为 1

    一个多星期以来 我一直在努力让 NuGet 正常工作 我终于让它可以在本地构建上运行 但不能在 TFS 2013 构建上运行 我将范围缩小到 NuGet 在团队构建期间没有发生 但是当我添加时 SolutionDir nuget nuget
  • C 中的文件处理 - 从文本文件列表中删除特定单词

    我使用以下代码从我的基本 C 程序填充一个简短的字典 void main FILE fp fp fopen c CTEMP Dictionary2 txt w fprintf fp Word to Dictionary 然而 我也希望删除某
  • React 应用程序中的handleCategoryClick 和handleSearchChange 问题

    我正在开发一个 React 应用程序 我已经实现了两个功能 handleCategoryClick and handleSearchChange 分别处理类别选择和搜索功能 在登陆页面上 这两个功能都可以完美运行 但是 当导航到另一个页面时
  • Struts 2 和 Hibernate 中的异常处理

    假设我们用Struts 2 Hibernate MySQL开发了一个网站 并且我们添加了一些try catch这里的块包含通过 Hibernate 进行的数据库调用 我的问题是 在 catch 块内 我正在向记录器发送适当的消息 这里我们不
  • 仅 Spring-MVC 需要哪些 jar?

    我需要在我的临时项目中运行 Spring MVC 同时我有最小的内存区域来存储所有的 jar 文件 所以任何人推荐我只需要 Spring MVC 而不是任何其他 jar 文件 提前致谢 根据maven spring webmvc3 1 2需
  • 将 UIImage 从 BGR 转换为 RGB

    正如标题所示 我在某些 UIImage 颜色空间转换方面遇到了一些麻烦 TL DR 版本是我需要一种将 BGR 格式的 UIIMage 转换为 RGB 的方法 这是我的应用程序中的事件流程 应用程序 获取图像 应用程序 转换为base64并
  • 在汇编中操作字符串 (MASM)

    data source BYTE Defense mechanism 0 target BYTE SIZEOF source DUP 0 code main PROC mov esi OFFSET target mov edi OFFSET
  • 了解 ZeroMQ

    因此 正如我在上一篇文章中所问的那样 我希望能够使用不同语言编写的程序或函数在它们之间进行通信 我最近遇到了 Zeromq 我试图弄清楚这是否可以帮助我 因为它提供了某种套接字 例如 zeromq 可以在用 python 编写的程序与用 C
  • Laravel 保护 Amazon s3 存储桶文件

    我正在使用 Amazon s3 但在这里我面临两个问题 1 当我提交表单时 我无法直接将文件上传到亚马逊服务器 我的意思是我必须将图像上传到upload folder在我的 PHP 服务器上 我必须从那里检索它们并将其上传到s3 serve
  • 如何通过 JDBC-ODBC 桥在 MS Access 中指定 null 值?

    我无法使用 MS Access sun jdbc odbc JdbcOdbcDriver 在PreparedStatement 上调用 setNull preparedStatement setNull index sqltype 有解决方
  • 使用 SET 变量进行 MySQL 查询

    我试图通过在围绕单个值使用大量 case 语句运行查询之前设置一些变量来清理 Go 调用 MySQL 查询的方式 我尝试运行的查询在控制台上运行良好 但由于语法问题而失败SELECT当通过 Go 运行它时 这样的事情可能吗 func d D
  • Android - Google 地图扩展 - IllegalArgumentException

    当我调用 createMarker 方法时 出现 IllegalArgumentException private void createMarker GoogleMap map MarkerOptions options OnMarker
  • 如何将 xbf 文件添加到 Visual Studio 项目

    我已经为 Windows 通用平台 Win 10 UWP 创建了一个类库 该库包含一些用户控件 当我将此库中的 dll 添加到 Win 10 UWP 应用程序并使用 UserControls 时 它会给出 XamlParseExceptio
  • 如何在 Angular 5 的嵌套组件中使用 Flex 布局?

    我正在创建一个应用程序 该应用程序具有使用 Angular 5 中的父子关系的多个组件 在我的主 app component html 中 我有这个结构
  • 有或没有持有者的单例 = 惰性初始化 vs 急切初始化?

    它是否正确 Using a 带支架的单例给出延迟初始化 因为该类SingletonHolder仅在以下情况下初始化Singleton getInstance 正在运行 这依赖于SingletonHolder仅在内部被引用Singleton