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年出版,到现在已经将 ...
随机推荐
- Java异常(输出[D@139a55问题)
简单给出一段代码说明问题: public class Main { public static void main(String[] args) { double a[]={1,4,3,2}; Sys ...
- 51nod 1231 记分牌
链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1231 一个得分合法等价于前k小的得分之和大于等于$\frac{k* ...
- [51nod1425]减减数
初始给定一个整数n.每次可以对其做一个操作,这个操作是将n减去他其中的某一位.得到新的一个数字n',然后继续操作,直到他变成0为止. 比如24这个例子,24 → 20 → 18 → 10 → 9 → ...
- 2017广东工业大学程序设竞赛E题(倒水)
Description 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把一个 ...
- Linux系统调优权威指南
1.关闭SELINUX功能1.1 修改配置文件,使关闭SELINUX永久生效sed 's#SELINUX=enforcing#SELINUX=disables#g' /etc/selinux/conf ...
- Spring框架学习笔记(3)——配置bean
1.属性注入 (1)根据setter方法属性注入,这里使用的是property标签.需要bean属性提供对应的setter方法,比如笔记(1)里的 HelloWorld使用的就是这种方法. <! ...
- css实现视差滚动效果
今天逛京东金融的时候发现他家网站首页的滚动效果看着很有意思,于是就做了一个,demo链接http://1.liwenyang.applinzi.com/index.html 大多数的视差滚动效果都是使 ...
- JavaScript八张思维导图—编程实践
JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...
- php switch case语句用法
- java.lang.NoClassDefFoundError: javax/mail/Authenticator
摘录自:http://stackoverflow.com/questions/1630002/java-lang-noclassdeffounderror-javax-mail-authenticat ...