延迟加载分为实例域与静态域二种
实例的延迟加载。主要看创建实例的成本。一般需要测试之后才决定是否使用延迟加载。利:消耗资源的对象延迟加载。弊:访问的线程会由于延迟加载变慢同时多线程情况下,需要同步。实现方式:一。 synchronized同步方法。private FieldType field;synchronized FieldType getField() { if (field == null)field = computeFieldValue(); return field;}二。DC检查更优。 Double-check idiom for lazy initialization of instance fieldsprivate volatile FieldType field; //注意必须使用volatile,volatile除了可见性之外,还有一个功能是避免编译器优化。 FieldType getField() { FieldType result = field; if (result == null) { // First check (no locking) synchronized(this) { //这样不会象1)中synchronized整个方法,导致在初始化成功之后,访问getInstance仍然要同步的低效. result = field; //这里使用result的原因是让result即使result由于JIT无序写入出现不为null并且没有完全初始化的情况,但是可以是能field要么为null,要么被完整初始化。此时field是null. if (result == null){ // Second check (with locking) field //field肯定是在result完全初始化之后的值。 field = result = computeFieldValue(); } } return result; }
private static class FieldHolder { static final FieldType field = computeFieldValue(); } static FieldType getField() { return FieldHolder.field; }
静态域的延迟加载-》演变成单例实现:
public SNSCacheUtil{ ...... private static class SingletonHolder { static SNSCacheUtil INSTANCE = new SNSCacheUtil(); } public static SNSCacheUtil getInstance() { return SingletonHolder.INSTANCE; } ...... }
参http://www.ibm.com/developerworks/cn/java/j-dcl.html