I woke up this morning thinking I
knew all there was to know about lazy loading singletons in Java. Boy,
was I wrong. Java doesn't cease to surprise me, even after all these
years.
First, why would you want to lazy load a singleton? In production,
you typically want to eagerly load all your singletons so you catch
errors early and take any performance hit up front, but in tests and
during development, you only want to load what you absolutely need so as
not to waste time.
Before Java 1.5, I lazy loaded singletons using plain old synchronization, simple but effective:
static Singleton instance;
public static synchronized
Singleton getInstance() {
if (instance == null)
instance == new Singleton();
return instance;
}
Changes to the memory model in 1.5 enabled the infamous Double-Checked
Locking (DCL) idiom. To implement DCL, you check a volatile field in the
common path and only synchronize when necessary:
static volatile
Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null)
instance == new Singleton();
}
}
return instance;
}
But volatile
isn't that much faster than synchronized
, synchronized
is pretty fast nowadays, and DCL requires more code, so even after 1.5 came out, I continued using plain old synchronization.
Imagine my surprise today when Jeremy Manson pointed me to the Initialization on Demand Holder (IODH) idiom
which requires very little code and has zero synchronization overhead. Zero
, as in even faster than volatile
. IODH requires the same number of lines of code as plain old synchronization, and it's faster than DCL!
IODH utilizes lazy class initialization. The JVM won't execute a
class's static initializer until you actually touch something in the
class. This applies to static nested classes, too. In the following
example, the JLS guarantees
the JVM will not initialize instance
until someone calls getInstance()
:
static class SingletonHolder {
static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
Why didn't IODH register in my brain sooner? I'm on the JMM mailing list
after all. I think I had a mental block due to the fact that exceptions
thrown in class initializers used to be difficult to debug, i.e. before
nested exceptions. If I recall correctly, you would get an ExceptionInInitializerError
(which would tromp the root exception) followed by a series of ClassNotFoundException
s. Lazy loading from an application thread didn't suffer this problem.
Today, exceptions in static initializers are easy enough to diagnose--they appear nested in the ExceptionInInitializerError
, so use IODH from now qualm free.
Update:
Credit where credit is due, Effective Java
(copyright 2001) detailed this pattern under item 48. It goes on to
point out that you still have to use synchronization or DCL in
non-static contexts.
I also switched singleton handling in my framework from
synchronization to DCL and saw another 10% performance boost (compared
to before I started using cglib's fast reflection). I only used one
thread in my micro-benchmark, so the boost to concurrency could be even
greater given that I replaced a heavily contended lock with a relatively
fine grained volatile field access.
分享到:
相关推荐
In this article I want to discuss the lazy loading mechanism provided by NHibernate. It is recommended for maximum flexibility to define all relations in your domain as lazy loadable. This is the ...
UITableView 與 Lazy Loading 結合 當cell 需要顯示照片時, 由NSURLConnect 去下載圖片.
NULL 博文链接:https://xdjava.iteye.com/blog/1745136
前端代码实现图片懒加载 , 内含完整的html5页面 , js 以及图片资源 , 有兴趣的朋友可以参考一下
移动端图片懒惰加载,直加载能看到的图片,当欢动手机屏幕新的图片才会加载,只需引入给的文件中的js和css再做一些简单的设置就能使用
懒惰的加载
React Lazy Loading - 很容易与 React 集成到 Lazyload 组件、图像等。它会监视元素并告诉您元素何时进入视口。 这样可以在视口中的组件和初始加载减少时执行任何操作。 实现“无限滚动”网站,在您滚动时加载和...
图像的反延迟加载, 在任何网页上加载所有图像 - 一旦页面加载即可。 图像的反延迟加载, 在任何网页上加载所有图像 - 一旦页面加载就会。 语言:English (United States)
Yii2 的延迟加载模块用于内容延迟加载的 Yii2 模块主要特点: 显示... 在应用程序配置文件的modules部分添加一个新模块,例如: 'modules' => [ 'lazyloading' => ['class' => 'denar90\lazyloading\LazyLoading' ,'m
Laravel开发-eloquent-log-lazy-loading 记录(或禁用)雄辩的延迟加载关系。
2.安装说明版本: 节点:14.15.1 Npm:6.14.8 React:17.0.1 从Github下载代码: git clone https://github.com/antoineratat/react_lazyloading.git 导航到项目目录。 cd react_intersection_observer 安装节点模块...
一个markdown-it插件,支持Chrome 75的本机图像延迟加载。... const lazy_loading = require('markdown-it-image-lazy-loading'); md.use(lazy_loading); md.render(`![](example.png“图片标题”)`); //
Ig-Lazy-Module-Loader This library helps with loading modules (features) in ...In the demo app there's two examples of lazy loading: java library - compiled first to jar and then to dex file android
今天起床,拿起手机开机第一时间当然是打开微信了,左右滑动Viewpager,发现它使用了一种叫惰性加载,或者说懒加载(lazy-loading)的方式加载Viewpager中的Fragment。效果如图: 什么是lazy-loading呢?顾名思义...
Apende como实现者懒惰加载Intersection Observer API和React JS的tus imagenes钩子useInfiniteScroll import { useRef , useEffect } from "react" ;export const useInfiniteScroll = ( { element , fetch } ) => ...
语言:Tiếng Việt 自动重新加载HAUI部分的注册页面时发生错误 在发生错误时自动重新加载HAUI部分的注册页面时发生错误503,504,404,...如果成功将调用ting
#Lazy在网络上加载图片 该存储库包含一些使用多种方法为网络延迟加载图像的简单示例:普通JavaScript,jQuery,[be] Lazy.js,LazyLoad.js,Lazy Load XT和Unveil。
Lazyloadinglistview 的异步加载功能简介功能为读取 /system/app 下的apk,然后从apk中获取每个应用程序的图标和名字每个apk消息的获取都增加了Thread.sleep() 模拟网络下载所消耗的时间。。。(学校上网收费,省点...
该文件压缩包中包含使用activiti流程实现的前台用户实名认证申请、与后台管理员的实名认证-人工审核功能和、使用ajax发送跨域请求的设置。