zoukankan      html  css  js  c++  java
  • 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;
    }

     

  • 相关阅读:
    Ubuntu忘记密码后强制修改密码
    搭建Jetbrains家族IDE授权服务器
    C#ComboBox绑定List
    字体包文件过大
    JS通过ActiveX读写ini配置文件
    NodeJS + express访问html、css、JS等静态资源文件
    VueJS搭建简单后台管理系统框架 (二) 模拟Ajax数据请求
    VueJS搭建简单后台管理系统框架(一)环境搭建
    ExtJS4.x Grid 单元格鼠标悬停提示
    IE9下Ajax缓存问题
  • 原文地址:https://www.cnblogs.com/hunterCecil/p/5630970.html
Copyright © 2011-2022 走看看