In software engineering, the Initialization on Demand Holder idiom (design pattern) is a lazy-loaded singleton. The idiom can be implemented in both single-threaded/serial and concurrent environments, but care must be taken to correctly implement the idiom under concurrent conditions.
Contents
1 Example Java Implementation
1.1 How it works
1.2 When to use it
1.3 When not to use it
Example Java ImplementationThis implementation is a well-performing and concurrent implementation valid in all versions of Java. The original implementation from Bill Pugh (see links below), based on the earlier work of Steve Quirk, has been modified to reduce the scope of LazyHolder.INSTANCE to private and to make the field final.
public class Something {
private Something() {
}
private static class LazyHolder {
public static final Something INSTANCE = new Something();
}
public static final Something getInstance() {
return LazyHolder.INSTANCE;
}
}
How it works
The implementation relies on the well-specified initialization phase of execution within the Java Virtual Machine (JVM); see section 12.4 of Java Language Specification (JLS) for details.
When the class Something is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables to initialize, the initialization completes trivially. The static class definition LazyHolder within it is not initialized until the JVM determines that LazyHolder must be executed. The static class LazyHolder is only executed when the static method getInstance is invoked on the class Something, and the first time this happens the JVM will load and initialize the LazyHolder class. The initialization of the LazyHolder class results in static variable INSTANCE being initialized by executing the (private) constructor for the outer class Something. Since the class initialization phase is guaranteed by the JLS to be serial, i.e., non-concurrent, no further synchronization is required in the static getInstance method during loading and initialization. And since the initialization phase writes the static variable INSTANCE in a serial operation, all subsequent concurrent invocations of the getInstance will return the same correctly initialized INSTANCE without incurring any additional synchronization overhead.
When to use it
Use this pattern if the initialization of the class is expensive and it cannot be done safely at class-loading time and the initialization is highly concurrent. The crux of the pattern is the safe removal of the synchronization overhead associated with accessing a singleton instance.
When not to use
itAvoid this idiom if the construction of INSTANCE can fail. If construction of INSTANCE fails, an invocation of Something.getInstance() will result in a java.lang.NoClassDefFoundError error. Handling, or mishandling, of these types of construction initialization failures is a common criticism of this idiom and the singleton pattern in general.
分享到:
相关推荐
Initialization on demand holder Strategy Observer Built-in Self made Decorator Description Singleton 确保类只有一个实例,并提供一个全局访问点。 Strategy 策略模式定义了可以相互替换的一组算法,让算法的...
holder”创建单例模式的理解,参考 Spring中单例的概念限于Spring上下文中,遵守约定 内部bean适用于setter注入和构造器注入,内部bean不能被复用 SpEL表达式 3. 高级装配 4 种自动装配 byName, byType, contructor, ...
PowerPC interrupt initialization analysis based on VxWorks.pdf
出现“TLS initialization failed”错误的主要原因可能是系统缺少OpenSSL库。OpenSSL是一个开源的库,包含了实现SSL和TLS协议所需的加密算法、证书处理等功能。在QT中进行HTTPS请求时,需要依赖OpenSSL来处理加密和...
标题 "JUnit 报 initializationError" 描述了一个在使用 JUnit 测试框架时常见的问题,即在执行测试时遇到 `initializationError`。这通常意味着在测试初始化阶段出现了错误,可能是由于测试类的静态初始化块、构造...
ApplicationInitialization for UI x64 ApplicationInitialization for UI x64
4. 以 DBA 用户登录,并使用以下命令:Sqlplus/nolog Sql>connect sys/change_on_install as sysdba 5. 关闭数据库:Sql>shutdown normal 6. 启动数据库:Sql>startup mount 7. 加载数据库:Sql>alter database open...
TIJ4 Initialization Cleanup
Net: Board Net Initialization Failed No ethernet found.解决方案,如实际开发中有遇到,仅供参考 1. 网卡没有插好或者网卡损坏。 2. 网卡的驱动程序没有正确加载。 3. 网线没有接好或者网线损坏。 4. 网络设备...
4. 静态内部类(Initialization on Demand Holder) 静态内部类实现单例模式的方式是利用了类的加载机制来保证实例的创建。只有当首次使用静态内部类的时候,Java虚拟机才会去加载这个类,类的加载是线程安全的,...
bf533的initialization中需要选择的.dxe工程Init_Sdram,配置在Poject Option - initialization ,烧录LDR需要选择,要和自己所应用的实际SDRAM配置一致才能启动成功
但自从Windows 2012出来之后,这部分ApplicationInitialization功能已经有内含在IIS8之中,可以直接进行设定就可以。不过微软也发布了针对针对前期的IIS单独模块:ApplicationInitialization Module for IIS 7.5 。
SQL>connect sys/change_on_install as sysdba 提示:已成功 SQL>shutdown normal 提示:数据库已经关闭 已经卸载数据库 ORACLE 例程已经关闭 SQL>startup mount 提示:ORACLE例程已经启动 Total System Global ...
"ApplicationInitialization for UI x64" 是一个专为64位操作系统设计的用户界面应用程序初始化模块。这个模块主要关注的是提升用户体验,确保UI(用户界面)在启动时能快速、稳定地加载,同时减少应用程序在启动...
解决:oracle_plsql连服务端时 Initialization error could initialize错误处理方法
SQL> connect sys/change_on_install as sysdba ``` 登录成功后,可以看到相应的提示信息。 4. **停止Oracle实例**: - 停止当前的Oracle实例: ``` SQL> shutdown normal ``` 正常情况下,系统会返回类似...
项目中碰到的问题
Application Initialization Failed(处理方案).md
标题中的“ApplicationInitialization”是指IIS(Internet Information Services)的一项特性,它允许在IIS 7中模拟IIS 8的行为,特别是在首次请求时提高应用的响应速度。这个特性主要解决的问题是,当一个Web应用...