第83项:慎用延迟初始化

  *延迟初始化(Lazy initialization)*是延迟到需要域的值时才将它初始化的行为。如果永远不需要这个值,这个域就永远不会被初始化。这种方法既适用于静态域,也适用于实例域。虽然延迟初始化主要是一种优化,但它也可以用来打破类和实例初始化中的有害循环[Bloch05, Puzzle 51]。

  就像大多数的优化一样,对于延迟初始化,最好的建议就是“除非绝对必要,否则就不要这么做”(第67项)。延迟初始化就像一把双刃剑。它降低了初始化类或者创建实例的开销,却增加了访问被延迟初始化的域的开销。根据延迟初始化的域最终需要初始化的比例、初始化这些域要多少开销,以及每个域多久被访问一次,延迟初始化(就像其他的许多优化一样)实际上降低了性能。

  也就是说,延迟初始化有它的好处。如果域只在类的实力部分被访问,并且初始化这个域的开销很高,可能就值得进行延迟初始化。要确定这一点,唯一的办法就是测量类在用和不用延迟初始化时的性能差别。

  当有多个线程时,延迟初始化是需要技巧的。如果两个或者多个线程共享一个延迟初始化的域,采用某种形式的同步是很重要的,否则就可能在成严重的Bug(第78项)。本项中讨论的所有初始化方法都是线程安全的。

  在大多数情况下,正常的初始化要优先于延迟初始化 。下面是正常初始化实例域的一个典型声明。注意其中使用了final修饰符(第17项)。

// Normal initialization of an instance field 
private final FieldType field = computeFieldValue();

  如果利用延迟初始化来破坏初始化循环,就要使用同步访问方法 ,因为它是最简单、最清晰的代替方法:

// Lazy initialization of instance field - synchronized accessor
private FieldType field;
private synchronized FieldType getField(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值