Effective Java 之-----关于延迟初始化
1、大多数情况下,正常的初始化要优先于延迟初始化。
private final FieldType field = computeFieldValue();
2、如果利用延迟优化来破坏初始化的循环,就要使用同步访问方法,因为它是最简单、最清楚的替代方法。
private FieldType field;
synchronized FieldType getField(){
if(field == null){
field = computeFieldValue();
}
return field;
}
3、如果出于性能考虑需要对静态域使用延迟初始化,就使用lazy initialization holder class 模式,保证类要到被用到的时候才会被初始化。
private static class FieldHolder{
static final FieldType field = computeFieldValue();
}
static FieldType getField(){
return FieldHolder.field;
}
当getField被第一次调用时,第一次读取FieldHolder.field,导致FieldHolder得到初始化。
4、如果出于性能考虑需要对实例域使用延迟初始化,就使用双重检查模式(double check idiom),这种模式避免了在域被初始化之后访问这个域时的开销。
private volatile FieldType field;
FieldType getField(){
FieldType result = field;
if(result == null){ //First check(no locking)
synchronized (this){
result = field;
if(result == null){//second check(with locking)
field = result = computeFieldValue();
}
}
}
return result;
}
两次检查域值,第一次检查时没有锁定,看这个域是否被初始化了;第二次检查时锁定,只有当第二次检查时表明这个域没有被初始化,才会调用computeFieldValue方法对这个域进行初始化。因为如果域已经被初始化就不会有锁定,域被声明为volatile很重要。
5、如果可以接收重复初始化,也可以考虑使用单重检查模式(single check idiom)
private volatile FieldType field;
private FieldType getField(){
FieldType result = field;
if(result == null){
field = result = computeFieldValue();
return result;
}
Effective Java 之-----关于延迟初始化的更多相关文章
- Effective Java 第三版——83. 明智谨慎地使用延迟初始化
Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...
- JAVA 双重检查锁定和延迟初始化
双重检查锁定的由来在Java程序中,有时需要推迟一些高开销的对象的初始化操作,并且只有在真正使用到这个对象的时候,才进行初始化,此时,就需要延迟初始化技术.延迟初始化的正确实现是需要一些技巧的,否则容 ...
- Java对象延迟初始化的实现
一.什么是延迟初始化? 在Java多线程程序中,有时候需要采用延迟初始化来降低初始化类和创建对象的开销. 延迟初始化实际上就是:当我们要进行一些高开销的对象初始化操作时,只有在使用这些对象时才进行初始 ...
- Java - 延迟初始化
延迟初始化(lazy initialization),也就是在真正被使用的时候才开始初始化的技巧. 不论是静态还是实例,都可以进行延迟初始化. 其本质是初始化开销和访问开销之间的权衡. 毕竟是一种优化 ...
- 从学习“单例模式”学到的Java知识:双重检查锁和延迟初始化
一切真是有缘,上午刚刚看完单例模式,还在为其中的代码块同步而兴奋,下午就遇见这篇文章:双重检查锁定与延迟初始化.我一看,文章开头语出惊人,说这是一种错误的优化,我说,难道上午学的东西下午就过时了吗?仔 ...
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- 双重检查锁定与延迟初始化(转自infoq)
很好的文章,转自http://www.infoq.com/cn/articles/double-checked-locking-with-delay-initialization 在java程序中,有 ...
- Effective Java通俗理解(下)
Effective Java通俗理解(上) 第31条:用实例域代替序数 枚举类型有一个ordinal方法,它范围该常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用 ...
- Effective Java 第三版——6. 避免创建不必要的对象
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
随机推荐
- 【转】TCP粘包分析
一 .两个简单概念长连接与短连接: 1.长连接 Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收. 2.短连接 Client方与Server每 ...
- CommonJS,AMD,RequireJS的区别
RequireJS实现了AMD的API. CommonJS是使用exports对象来定义模块的一种方法,它定义了模块的内容.简单地实现一个CommonJS的定义就像下面这样: // someModul ...
- BZOJ 1800: [Ahoi2009]fly 飞行棋【思维题,n^4大暴力】
1800: [Ahoi2009]fly 飞行棋 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1689 Solved: 1335[Submit][St ...
- 基于.netcore 开发的轻量Rpc框架
Rpc原理详解 博客上已经有人解释的很详细了,我就不在解释了.传送门 项目简介 项目是依赖于.net core2.0版本,内部都是依靠IOC来实现的,方便做自定义扩展.底层的通信是采用socket,s ...
- Spring框架学习笔记(1)——HelloWorld
1.创建一个新的项目,并添加Spring框架 2.创建HelloWorld.java package com.broadtext.beans.helloworld; public class Hell ...
- HTML5 Canvas 数据持久化存储之属性列表
属性列表想必大家都不会陌生,正常用 HTML5 来做的属性列表大概就是用下拉菜单之类的,而且很多情况下,下拉列表还不够好看,怎么办?我试着用 HT for Web 来实现属性栏点击按钮弹出多功能选框, ...
- github 中删除仓库
删除时,填充的名字是库的名字
- 邓_ ThinkPhp框架
登陆功能是PHP程序设计中常见的功能.本文ThinkPHP实例主要完成注册成功后进入首页,并告诉你是登录用户的功能.具体实现步骤如下: 第一步:在config.php文件中加上: 1 'USER_AU ...
- 利用光场进行深度图估计(Depth Estimation)算法之二——匹配算法
光场相机由于能够捕获相机内部光线的强度和方向而得到整个光场,可以实现重聚焦(refocus)和视角变换等功能.进而可以进行深度估计获取深度图,前面说过利用重聚焦的图像进行深度估计,今天说一下利用不同视 ...
- sql子查询
一.子查询入门: 1.单值子查询: 单值子查询的唯一限制:子查询的返回值必须只有一行记录,而且只能有一列(又被称为标量子查询). 可以使用在select语句的列表.表达式中,以及where语句中等. ...